一、使用TS

安装TypeScript

有两种主要的方式来获取TypeScript工具:

  • 通过npm(Node.js包管理器)
  • 安装Visual Studio的TypeScript插件

针对使用npm的用户:

npm install -g typescript

安装完成后我们可以使用 tsc 命令来执行 TypeScript 的相关代码,以下是查看版本号:

$ tsc -v
Version 4.9.3

然后我们新建一个 app.ts 的文件,代码如下:

var message:string = "Hello World" 
console.log(message)

运行

tsc app.ts

二、tsconfig配置文件

file

file 数组类型。它表示由 ts 管理的 文件 的具体路径,可以是相对或绝对路径。
这些文件内部有依赖的模块(或者引入了哪些模块),编译器也会搜索到依赖模块进行编译。
如果某些模块并没有在项目中引入,虽然在项目目录中也不会被编译。
如果不指定 files ,项目目录下的所有文件都会被编译器编译。

{
  // 指定需要编译文件 否则默认当前目录下除了exclude之外的所有.ts, .d.ts,.tsx 文件
   "files": ["./src/**/*"]
}

【注意】files 中不支持 glob 匹配模式的路径。

{
  "compilerOptions": {

    /* 基本选项 */
    "target": "es5",                       // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
    "module": "commonjs",                  // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
    "lib": [],                             // 指定要包含在编译中的库文件
    "allowJs": true,                       // 允许编译 javascript 文件
    "checkJs": true,                       // 报告 javascript 文件中的错误
    "jsx": "preserve",                     // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
    "declaration": true,                   // 生成相应的 '.d.ts' 文件
    "sourceMap": true,                     // 生成相应的 '.map' 文件
    "outFile": "./",                       // 将输出文件合并为一个文件
    "outDir": "./",                        // 指定输出目录
    "rootDir": "./",                       // 用来控制输出目录结构 --outDir.
    "removeComments": true,                // 删除编译后的所有的注释
    "noEmit": true,                        // 不生成输出文件
    "importHelpers": true,                 // 从 tslib 导入辅助工具函数
    "isolatedModules": true,               // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似).

    /* 严格的类型检查选项 */
    "strict": true,                        // 启用所有严格类型检查选项
    "noImplicitAny": true,                 // 在表达式和声明上有隐含的 any类型时报错
    "strictNullChecks": true,              // 启用严格的 null 检查
    "noImplicitThis": true,                // 当 this 表达式值为 any 类型的时候,生成一个错误
    "alwaysStrict": true,                  // 以严格模式检查每个模块,并在每个文件里加入 'use strict'

    /* 额外的检查 */
    "noUnusedLocals": true,                // 有未使用的变量时,抛出错误
    "noUnusedParameters": true,            // 有未使用的参数时,抛出错误
    "noImplicitReturns": true,             // 并不是所有函数里的代码都有返回值时,抛出错误
    "noFallthroughCasesInSwitch": true,    // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿)

    /* 模块解析选项 */
    "moduleResolution": "node",            // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
    "baseUrl": "./",                       // 用于解析非相对模块名称的基目录
    "paths": {},                           // 模块名到基于 baseUrl 的路径映射的列表
    "rootDirs": [],                        // 根文件夹列表,其组合内容表示项目运行时的结构内容
    "typeRoots": [],                       // 包含类型声明的文件列表
    "types": [],                           // 需要包含的类型声明文件名列表
    "allowSyntheticDefaultImports": true,  // 允许从没有设置默认导出的模块中默认导入。

    /* Source Map Options */
    "sourceRoot": "./",                    // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
    "mapRoot": "./",                       // 指定调试器应该找到映射文件而不是生成文件的位置
    "inlineSourceMap": true,               // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
    "inlineSources": true,                 // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性

    /* 其他选项 */
    "experimentalDecorators": true,        // 启用装饰器
    "emitDecoratorMetadata": true          // 为装饰器提供元数据的支持
  }
}

include 和 exclude

include 和 exclude 都是数组类型。
include 用于表示 ts 管理的文件。
exclude 用于表示 ts 排除的文件(即不被编译的文件)。
文件列表可以使用 glob 匹配模式列表,支持的 glob 通配符有:

*:匹配0或多个字符(不包括目录分隔符)。
?:匹配一个任意字符(不包括目录分隔符)。
**/:递归匹配任意子目录。

tsc --init  //生成tsconfig.js文件

运行

tsc --watch

三、数据类型

类型

例子

描述

number

1, -33, 2.5

任意数字

string

‘hi’, “hi”, hi

任意字符串

boolean

true、false

布尔值true或false

字面量

其本身

限制变量的值就是该字面量的值

any

*

任意类型

unknown

*

类型安全的any

void

空值(undefined)

没有值(或undefined)

never

没有值

不能是任何值

object

{name:‘孙悟空’}

任意的JS对象

array

[1,2,3]

任意JS数组

tuple

[4,5]

元素,TS新增类型,固定长度数组

enum

enum{A, B}

枚举,TS中新增类型

3.1) number类型

let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;

3.2) boolean类型

let isDone: boolean = false;

3.3) 字面量

  • 也可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围
let color: 'red' | 'blue' | 'black';
let num: 1 | 2 | 3 | 4 | 5;

3.4) any

let d: any = 4;
d = 'hello';
d = true;

3.5) unknown

let notSure: unknown = 4;
notSure = 'hello';

3.5) void

let unusable: void = undefined;

3.6) never

function error(message: string): never {
  throw new Error(message);
}

3.7) object(没啥用)

let obj: object = {};

array

let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

3.8) tuple元组

let x: [string, number];
x = ["hello", 10];

3.9) enum枚举

enum Color {
  Red,
  Green,
  Blue,
}
let c: Color = Color.Green;

enum Color {
  Red = 1,
  Green,
  Blue,
}
let c: Color = Color.Green;

enum Color {
  Red = 1,
  Green = 2,
  Blue = 4,
}
let c: Color = Color.Green;

3.10) 类型断言

有些情况下,变量的类型对于我们来说是很明确,但是TS编译器却并不清楚,此时,可以通过类型断言来告诉编译器变量的类型,断言有两种形式:
第一种

let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length;

第二种

let someValue: unknown = "this is a string";
let strLength: number = (<string>someValue).length;
let [a,b]=[11,'abc'] as [number,string];
let str="abc" as const   //不可以修改
let arr=<const>[11,22,33];  //不可以修改

3.11) keyof

作用: 获取接口、对象、类等所有的属性名组成的联合类型。

interface Person{
  name: string;
  age: number;
}
type K1 = keyof Person;
type K2 = keyof Person[];

一、使用TS

安装TypeScript

有两种主要的方式来获取TypeScript工具:

  • 通过npm(Node.js包管理器)
  • 安装Visual Studio的TypeScript插件

针对使用npm的用户:

npm install -g typescript

安装完成后我们可以使用 tsc 命令来执行 TypeScript 的相关代码,以下是查看版本号:

$ tsc -v
Version 4.9.3

然后我们新建一个 app.ts 的文件,代码如下:

var message:string = "Hello World" 
console.log(message)

运行

tsc app.ts

二、tsconfig配置文件

file

file 数组类型。它表示由 ts 管理的 文件 的具体路径,可以是相对或绝对路径。
这些文件内部有依赖的模块(或者引入了哪些模块),编译器也会搜索到依赖模块进行编译。
如果某些模块并没有在项目中引入,虽然在项目目录中也不会被编译。
如果不指定 files ,项目目录下的所有文件都会被编译器编译。

{
  // 指定需要编译文件 否则默认当前目录下除了exclude之外的所有.ts, .d.ts,.tsx 文件
   "files": ["./src/**/*"]
}

【注意】files 中不支持 glob 匹配模式的路径。

{
  "compilerOptions": {

    /* 基本选项 */
    "target": "es5",                       // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
    "module": "commonjs",                  // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
    "lib": [],                             // 指定要包含在编译中的库文件
    "allowJs": true,                       // 允许编译 javascript 文件
    "checkJs": true,                       // 报告 javascript 文件中的错误
    "jsx": "preserve",                     // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
    "declaration": true,                   // 生成相应的 '.d.ts' 文件
    "sourceMap": true,                     // 生成相应的 '.map' 文件
    "outFile": "./",                       // 将输出文件合并为一个文件
    "outDir": "./",                        // 指定输出目录
    "rootDir": "./",                       // 用来控制输出目录结构 --outDir.
    "removeComments": true,                // 删除编译后的所有的注释
    "noEmit": true,                        // 不生成输出文件
    "importHelpers": true,                 // 从 tslib 导入辅助工具函数
    "isolatedModules": true,               // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似).

    /* 严格的类型检查选项 */
    "strict": true,                        // 启用所有严格类型检查选项
    "noImplicitAny": true,                 // 在表达式和声明上有隐含的 any类型时报错
    "strictNullChecks": true,              // 启用严格的 null 检查
    "noImplicitThis": true,                // 当 this 表达式值为 any 类型的时候,生成一个错误
    "alwaysStrict": true,                  // 以严格模式检查每个模块,并在每个文件里加入 'use strict'

    /* 额外的检查 */
    "noUnusedLocals": true,                // 有未使用的变量时,抛出错误
    "noUnusedParameters": true,            // 有未使用的参数时,抛出错误
    "noImplicitReturns": true,             // 并不是所有函数里的代码都有返回值时,抛出错误
    "noFallthroughCasesInSwitch": true,    // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿)

    /* 模块解析选项 */
    "moduleResolution": "node",            // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
    "baseUrl": "./",                       // 用于解析非相对模块名称的基目录
    "paths": {},                           // 模块名到基于 baseUrl 的路径映射的列表
    "rootDirs": [],                        // 根文件夹列表,其组合内容表示项目运行时的结构内容
    "typeRoots": [],                       // 包含类型声明的文件列表
    "types": [],                           // 需要包含的类型声明文件名列表
    "allowSyntheticDefaultImports": true,  // 允许从没有设置默认导出的模块中默认导入。

    /* Source Map Options */
    "sourceRoot": "./",                    // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
    "mapRoot": "./",                       // 指定调试器应该找到映射文件而不是生成文件的位置
    "inlineSourceMap": true,               // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
    "inlineSources": true,                 // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性

    /* 其他选项 */
    "experimentalDecorators": true,        // 启用装饰器
    "emitDecoratorMetadata": true          // 为装饰器提供元数据的支持
  }
}

include 和 exclude

include 和 exclude 都是数组类型。
include 用于表示 ts 管理的文件。
exclude 用于表示 ts 排除的文件(即不被编译的文件)。
文件列表可以使用 glob 匹配模式列表,支持的 glob 通配符有:

*:匹配0或多个字符(不包括目录分隔符)。
?:匹配一个任意字符(不包括目录分隔符)。
**/:递归匹配任意子目录。

tsc --init  //生成tsconfig.js文件

运行

tsc --watch

三、数据类型

类型

例子

描述

number

1, -33, 2.5

任意数字

string

‘hi’, “hi”, hi

任意字符串

boolean

true、false

布尔值true或false

字面量

其本身

限制变量的值就是该字面量的值

any

*

任意类型

unknown

*

类型安全的any

void

空值(undefined)

没有值(或undefined)

never

没有值

不能是任何值

object

{name:‘孙悟空’}

任意的JS对象

array

[1,2,3]

任意JS数组

tuple

[4,5]

元素,TS新增类型,固定长度数组

enum

enum{A, B}

枚举,TS中新增类型

3.1) number类型

let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;

3.2) boolean类型

let isDone: boolean = false;

3.3) 字面量

  • 也可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围
let color: 'red' | 'blue' | 'black';
let num: 1 | 2 | 3 | 4 | 5;

3.4) any

let d: any = 4;
d = 'hello';
d = true;

3.5) unknown

let notSure: unknown = 4;
notSure = 'hello';

3.5) void

let unusable: void = undefined;

3.6) never

function error(message: string): never {
  throw new Error(message);
}

3.7) object(没啥用)

let obj: object = {};

array

let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

3.8) tuple元组

let x: [string, number];
x = ["hello", 10];

3.9) enum枚举

enum Color {
  Red,
  Green,
  Blue,
}
let c: Color = Color.Green;

enum Color {
  Red = 1,
  Green,
  Blue,
}
let c: Color = Color.Green;

enum Color {
  Red = 1,
  Green = 2,
  Blue = 4,
}
let c: Color = Color.Green;

3.10) 类型断言

有些情况下,变量的类型对于我们来说是很明确,但是TS编译器却并不清楚,此时,可以通过类型断言来告诉编译器变量的类型,断言有两种形式:
第一种

let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length;

第二种

let someValue: unknown = "this is a string";
let strLength: number = (<string>someValue).length;
let [a,b]=[11,'abc'] as [number,string];
let str="abc" as const   //不可以修改
let arr=<const>[11,22,33];  //不可以修改

3.11) keyof

作用: 获取接口、对象、类等所有的属性名组成的联合类型。

interface Person{
  name: string;
  age: number;
}
type K1 = keyof Person;
type K2 = keyof Person[];

typescript 类型如何重写一个值的类型 typescript class类型_前端

3.12) typeof

ts中的typeof是根据已有的变量获取变量的类型的方法,以简化代码的书写。

interface Person{
  name:string
  age:number
}
const person:Person =  {name:"小明",age:21};
type TPerson = typeof person;

typescript 类型如何重写一个值的类型 typescript class类型_typescript_02

3.13) in

in用于取联合类型的值。主要用于数组和对象的构造。

type name = 'firstName' | 'lastName';
type TName = {
  [key in name]: string;
};

四、class 类

基本语法

// 通过class创建类
class Animal {
    // 类的属性
    name: string;
    // 类的构造器
    constructor(name: string) {
        this.name = name;
    }
    // 类的方法
    sayHello():void{
        alert("hello animal:"+this.name);
    }
}
// 实例化类
var tom = new Animal("tom");
tom.sayHello();

类的继承

public修饰符---- 公共的:类中成员的默认修饰符,代表是公共的,任何位置都可以访问类中的成员
private修饰符—私有的:类中的成员如果使用private来修饰,那么外部是无法访问这个成员数据的,当然子类中也是无法访问该成员数据的
protected修饰符—受保护的:类中的成员如果使用protected来修饰,那么外部是无法访问这个成员数据的,但是子类中是可以访问该成员数据的
readonly 修饰成员的可修改性

// 通过class创建类
class Animal {
    // 类的属性
    name: string;

    // 类的构造器
    constructor(name: string) {
        this.name = name;
    }

    // 类的方法
    sayHello(): void {
        alert("hello animal:" + this.name);
    }
}

// 继承Animal
class Cat extends Animal {
    // 重写方法
    sayHello(): void {
        alert("hello cat:" + this.name);
    }
}

class Dog extends Animal {
    sayHello(): void {
        alert("hello dog:" + this.name);
    }
}

修饰符 private 私有的,外部不能访问

class Animal {
    private name: string; // 这里把name修饰符改为private

    constructor(name: string) {
        this.name = name;
    }

    sayHello(): void {
        alert("hello animal:" + this.name);
    }
}

class Cat extends Animal {
    sayHello(): void {
        alert("hello cat:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
    }
}

class Dog extends Animal {
    sayHello(): void {
        alert("hello dog:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
    }
}

Get/Set访问器

class Animal {
    private _name: string;

  //通过get和set解决子类不能引用父类private修饰的属性的问题
    get name(): string { 
         console.log("触发get");
     
        return this._name;
    }

    set name(name: string) {
        console.log("触发set");
    
        this._name = name;
    }

    constructor(name: string) {
        this._name = name;
    }

    sayHello(): void {
        alert("hello animal:" + this._name);
    }
}

class Cat extends Animal {
    sayHello(): void {
        alert("hello cat:" + this.name); 
    }
}

class Dog extends Animal {
    sayHello(): void {
        alert("hello dog:" + this.name); 
    }
}

//使用
 new Cat().name="加菲猫"

静态属性

class Person {
    static weigth: Number = 100; //重
    static height: Number = 180   //高
}

var width: Number = Person.weigth;

函数

基本语法

function add(x:number,y:number):number{
    return x+y;
}

var myAdd = function(x:number,y:number):number{
    return x+y;
}

单泛型

function add<T>( val : T) : T{
 console.log(typeof val);
         return val
}
// 在调用的时候确定,自定义类型为number 传入 数字类型的值
const arr1 = add<number>(1)

多泛型

// 传入 规定参数类型的值 ,返回 规定参数类型的值
function getMsg<T1,T2>(val : T1 , str : T2) : [T1,T2]{
    return [val , str]
}

const arr = getMsg<string,number>('周杰伦',28.8)

abstract 抽象类

抽象类不能被实例化,
抽象类的成员可以不是抽象成员,但是有抽象成员的类必须是抽象类。
子类继承抽象类必须重写抽象类的抽象方法。
子类可以是一个抽象类,表示该子类必须有这个行为。

abstract class Person{
    abstract eat():any;
}
class Xiaoming extends Person{
     food:string;
     constructor(food:string){
         super()
         this.food=food
     }
      eat(){
          console.log("小明会吃,正在吃"+this.food);
      
      }
}
var xiaoming=new Xiaoming("窝窝头")
xiaoming.eat()

interface 接口

typescript中接口就是对json数据进行约束或者对类进行拓展,约束json数据的时候主要是对对象数据进行约束,规范对象数据的内部数据格式必须和接口一致。

interface PersonIf{
    name:string;
    age:number;
    sex:boolean
}
function getPerson(obj:PersonIf):string{
    return ''
}
var obejct={
    name:'小孩',
    age:18,
    sex:false
}
getPerson(obejct)

对象约束

interface obj{
    [index:string]:any
}
let duixiang:obj={
    name:'xiaozhi',
    sex:18,
    jop:{
        p1:'老师',
        p2:'家长'
    }
}
console.log(duixiang.jop.p1,duixiang.name);

接口对类的扩展

interface PersonIf{
    name:string;
    age:number;
    kouhong():any;
}
class person implements PersonIf{
    name:string;
    age:number;
    constructor(name:string,age:number){
        this.name=name
        this.age=age
    }
    kouhong(){
        console.log(this.name+'今年'+this.age+'岁,所以涂口红');
    }
}
var p=new person("张三",18)
console.log(p.kouhong());

namespace 命名空间

namespace A{
   export class a{
        name:string|undefined
        getName():any{
            console.log(this.name);
            return this.name
        }
    }
}
namespace B{
 export  class a{
        name:string|undefined
        getName():any{
            console.log(this.name);
            return this.name
        }
    }
}
var Aa=new A.a()
var Ba=new B.a

五、Decorator装饰器

装饰器是一个方法,可以向一个类、方法、属性、参数注入内容,用于扩展其功能。
装饰器执行顺序 属性装饰器>方法装饰器>方法参数装饰器>类装饰器
语法

@装饰器名(param:any){...}

主要:要支持装饰器,需要在ts配置文件中打开:

"experimentalDecorators": true,

1.无参类装饰器

function logDom(params:any){
    //param表示的是类本身
    // 向当前类添加属性
   params.protoType.age='12'
    // 向类里面添加方法
    params.protoType.getAge=function(){
        console.log("11");   
    }
}
@logDom
class Dome{
    constructor(){}
    show():void{
        console.log("累呀");
    }
}
var dome:any=new Dome()
console.log(dome.age);
dome.getAge()

2.有参装饰器:返回一个函数

function logDom(params:any){
    //param表示的是类本身
    // 向当前类添加属性
    console.log(params)
    return function(target:any){
        target.prototype.age='12'
        // 向类里面添加方法
        target.prototype.getAge=function(){
            console.log("11");
        
        }
    }
  
}
@logDom("你好")
class Dome{
    constructor(){}
    show():void{
        console.log("累呀");
    }
}
var dome:any=new Dome()
console.log(dome.age);
dome.getAge()

3.属性装饰器

function decorateDome(params:any){
    return function(target:any,atrr:any){
        target[atrr]=params
    }
  
}
class Dome{
    @decorateDome("属性装饰器")
    url:string|undefined;
    constructor(){
        // this.url="我是一个url"
    }
    getUrl(){
        console.log(this.url);
    
    }
}
var dome=new Dome()
console.log(dome.url);

4.方法装饰器

function decorateDome(params:any){
    return function(target:any,methodName:any,desc:any){
      console.log(params);
      console.log(target);
      console.log(methodName);
      console.log(desc);  
    }   
}
class Dome{
    url:string|undefined;
    constructor(){
        // this.url="我是一个url"
    }
    @decorateDome("属性装饰器")
    getUrl(){
        console.log(this.url);
    
    }
}
var dome=new Dome()

六、webpack

安装 webpack和webpack-cli

cnpm i webpack webpack-cli  项目和全局都安装一次
cnpm i ts-loader

生成 tsconfig.json文件

tsc --init  // "outDir": "./dist",
"dev":"webpack serve",
const path = require('path')//引入内置path方便得到绝对路径
const HtmlWebpackPlugin = require('html-webpack-plugin')//引入模板组件


module.exports = {
    mode: 'development',//开发模式
    entry: './src/index.ts',//入口文件地址
    output: {
        path: path.resolve(__dirname, "./dist"),//出口文件,即打包后的文件存放地址
        filename: 'bundle.js' //文件名
    },
    devServer: {

    },
    resolve: {
        extensions:['.ts', '.js', '.cjs', '.json'] //配置文件引入时省略后缀名
    },
    module: {
        rules: [
            {
                test: /\.ts$/, //匹配规则 以ts结尾的文件
                loader: 'ts-loader', //对应文件采用ts-loader进行编译
                exclude:/node_modules/  //忽略node-modules
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({ 
            template: './public/index.html' //使用模板地址
        })
    ]
}

## 3.12) typeof

ts中的typeof是根据已有的变量获取变量的类型的方法,以简化代码的书写。

~~~typescript
interface Person{
  name:string
  age:number
}
const person:Person =  {name:"小明",age:21};
type TPerson = typeof person;
~~~

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=images%2FTypeScript%2F1711613057453.png&pos_id=img-gJQySmhL-1711613126384)

![image.png](https://img-blog.csdnimg.cn/img_convert/3f2768e49d607fae1e9174a0c5bae780.png)3.13) in

in用于取联合类型的值。主要用于数组和对象的构造。

```javascript
type name = 'firstName' | 'lastName';
type TName = {
  [key in name]: string;
};

四、class 类

基本语法

// 通过class创建类
class Animal {
    // 类的属性
    name: string;
    // 类的构造器
    constructor(name: string) {
        this.name = name;
    }
    // 类的方法
    sayHello():void{
        alert("hello animal:"+this.name);
    }
}
// 实例化类
var tom = new Animal("tom");
tom.sayHello();

类的继承

public修饰符---- 公共的:类中成员的默认修饰符,代表是公共的,任何位置都可以访问类中的成员
private修饰符—私有的:类中的成员如果使用private来修饰,那么外部是无法访问这个成员数据的,当然子类中也是无法访问该成员数据的
protected修饰符—受保护的:类中的成员如果使用protected来修饰,那么外部是无法访问这个成员数据的,但是子类中是可以访问该成员数据的
readonly 修饰成员的可修改性

// 通过class创建类
class Animal {
    // 类的属性
    name: string;

    // 类的构造器
    constructor(name: string) {
        this.name = name;
    }

    // 类的方法
    sayHello(): void {
        alert("hello animal:" + this.name);
    }
}

// 继承Animal
class Cat extends Animal {
    // 重写方法
    sayHello(): void {
        alert("hello cat:" + this.name);
    }
}

class Dog extends Animal {
    sayHello(): void {
        alert("hello dog:" + this.name);
    }
}

修饰符 private 私有的,外部不能访问

class Animal {
    private name: string; // 这里把name修饰符改为private

    constructor(name: string) {
        this.name = name;
    }

    sayHello(): void {
        alert("hello animal:" + this.name);
    }
}

class Cat extends Animal {
    sayHello(): void {
        alert("hello cat:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
    }
}

class Dog extends Animal {
    sayHello(): void {
        alert("hello dog:" + this.name); //这里会报错,因为无法引用父类private修饰的属性
    }
}

Get/Set访问器

class Animal {
    private _name: string;

  //通过get和set解决子类不能引用父类private修饰的属性的问题
    get name(): string { 
         console.log("触发get");
     
        return this._name;
    }

    set name(name: string) {
        console.log("触发set");
    
        this._name = name;
    }

    constructor(name: string) {
        this._name = name;
    }

    sayHello(): void {
        alert("hello animal:" + this._name);
    }
}

class Cat extends Animal {
    sayHello(): void {
        alert("hello cat:" + this.name); 
    }
}

class Dog extends Animal {
    sayHello(): void {
        alert("hello dog:" + this.name); 
    }
}

//使用
 new Cat().name="加菲猫"

静态属性

class Person {
    static weigth: Number = 100; //重
    static height: Number = 180   //高
}

var width: Number = Person.weigth;

函数

基本语法

function add(x:number,y:number):number{
    return x+y;
}

var myAdd = function(x:number,y:number):number{
    return x+y;
}

单泛型

function add<T>( val : T) : T{
 console.log(typeof val);
         return val
}
// 在调用的时候确定,自定义类型为number 传入 数字类型的值
const arr1 = add<number>(1)

多泛型

// 传入 规定参数类型的值 ,返回 规定参数类型的值
function getMsg<T1,T2>(val : T1 , str : T2) : [T1,T2]{
    return [val , str]
}

const arr = getMsg<string,number>('周杰伦',28.8)

abstract 抽象类

抽象类不能被实例化,
抽象类的成员可以不是抽象成员,但是有抽象成员的类必须是抽象类。
子类继承抽象类必须重写抽象类的抽象方法。
子类可以是一个抽象类,表示该子类必须有这个行为。

abstract class Person{
    abstract eat():any;
}
class Xiaoming extends Person{
     food:string;
     constructor(food:string){
         super()
         this.food=food
     }
      eat(){
          console.log("小明会吃,正在吃"+this.food);
      
      }
}
var xiaoming=new Xiaoming("窝窝头")
xiaoming.eat()

interface 接口

typescript中接口就是对json数据进行约束或者对类进行拓展,约束json数据的时候主要是对对象数据进行约束,规范对象数据的内部数据格式必须和接口一致。

interface PersonIf{
    name:string;
    age:number;
    sex:boolean
}
function getPerson(obj:PersonIf):string{
    return ''
}
var obejct={
    name:'小孩',
    age:18,
    sex:false
}
getPerson(obejct)

对象约束

interface obj{
    [index:string]:any
}
let duixiang:obj={
    name:'xiaozhi',
    sex:18,
    jop:{
        p1:'老师',
        p2:'家长'
    }
}
console.log(duixiang.jop.p1,duixiang.name);

接口对类的扩展

interface PersonIf{
    name:string;
    age:number;
    kouhong():any;
}
class person implements PersonIf{
    name:string;
    age:number;
    constructor(name:string,age:number){
        this.name=name
        this.age=age
    }
    kouhong(){
        console.log(this.name+'今年'+this.age+'岁,所以涂口红');
    }
}
var p=new person("张三",18)
console.log(p.kouhong());

namespace 命名空间

namespace A{
   export class a{
        name:string|undefined
        getName():any{
            console.log(this.name);
            return this.name
        }
    }
}
namespace B{
 export  class a{
        name:string|undefined
        getName():any{
            console.log(this.name);
            return this.name
        }
    }
}
var Aa=new A.a()
var Ba=new B.a

五、Decorator装饰器

装饰器是一个方法,可以向一个类、方法、属性、参数注入内容,用于扩展其功能。
装饰器执行顺序 属性装饰器>方法装饰器>方法参数装饰器>类装饰器
语法

@装饰器名(param:any){...}

主要:要支持装饰器,需要在ts配置文件中打开:

"experimentalDecorators": true,

1.无参类装饰器

function logDom(params:any){
    //param表示的是类本身
    // 向当前类添加属性
   params.protoType.age='12'
    // 向类里面添加方法
    params.protoType.getAge=function(){
        console.log("11");   
    }
}
@logDom
class Dome{
    constructor(){}
    show():void{
        console.log("累呀");
    }
}
var dome:any=new Dome()
console.log(dome.age);
dome.getAge()

2.有参装饰器:返回一个函数

function logDom(params:any){
    //param表示的是类本身
    // 向当前类添加属性
    console.log(params)
    return function(target:any){
        target.prototype.age='12'
        // 向类里面添加方法
        target.prototype.getAge=function(){
            console.log("11");
        
        }
    }
  
}
@logDom("你好")
class Dome{
    constructor(){}
    show():void{
        console.log("累呀");
    }
}
var dome:any=new Dome()
console.log(dome.age);
dome.getAge()

3.属性装饰器

function decorateDome(params:any){
    return function(target:any,atrr:any){
        target[atrr]=params
    }
  
}
class Dome{
    @decorateDome("属性装饰器")
    url:string|undefined;
    constructor(){
        // this.url="我是一个url"
    }
    getUrl(){
        console.log(this.url);
    
    }
}
var dome=new Dome()
console.log(dome.url);

4.方法装饰器

function decorateDome(params:any){
    return function(target:any,methodName:any,desc:any){
      console.log(params);
      console.log(target);
      console.log(methodName);
      console.log(desc);  
    }   
}
class Dome{
    url:string|undefined;
    constructor(){
        // this.url="我是一个url"
    }
    @decorateDome("属性装饰器")
    getUrl(){
        console.log(this.url);
    
    }
}
var dome=new Dome()

六、webpack

安装 webpack和webpack-cli

cnpm i webpack webpack-cli  项目和全局都安装一次
cnpm i ts-loader

生成 tsconfig.json文件

tsc --init  // "outDir": "./dist",
"dev":"webpack serve",
const path = require('path')//引入内置path方便得到绝对路径
const HtmlWebpackPlugin = require('html-webpack-plugin')//引入模板组件


module.exports = {
    mode: 'development',//开发模式
    entry: './src/index.ts',//入口文件地址
    output: {
        path: path.resolve(__dirname, "./dist"),//出口文件,即打包后的文件存放地址
        filename: 'bundle.js' //文件名
    },
    devServer: {

    },
    resolve: {
        extensions:['.ts', '.js', '.cjs', '.json'] //配置文件引入时省略后缀名
    },
    module: {
        rules: [
            {
                test: /\.ts$/, //匹配规则 以ts结尾的文件
                loader: 'ts-loader', //对应文件采用ts-loader进行编译
                exclude:/node_modules/  //忽略node-modules
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({ 
            template: './public/index.html' //使用模板地址
        })
    ]
}