Skip to content

速览TypeScript(进阶) #7

Description

@jappp

进阶

1. 类型别名

// 类型别名用来给一个类型起个新名字。typeName=string;typeNameResolver=()=>string;typeNameOrResolver=Name|NameResolver;functiongetName(n: NameOrResolver): Name{if(typeofn==='string'){returnn;}else{returnn();}}

2. 字符串字面量类型

// 字符串字面量类型用来约束取值只能是某几个字符串中的一个。// 类型别名与字符串字面量类型都是使用 type 进行定义。typeEventNames='click'|'scroll'|'mousemove';functionhandleEvent(ele: Element,event: EventNames){// do something}handleEvent(document.getElementById('hello'),'scroll');// 没问题handleEvent(document.getElementById('world'),'dblclick');// 报错,event 不能为 'dblclick'

3. 枚举

// 枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。 枚举使用 enum 关键字来定义:// 枚举成员会被赋值为从 0 开始递增的数字,同时也会对枚举值到枚举名进行反向映射:enumDays{Sun,Mon,Tue,Wed,Thu,Fri,Sat};// 枚举项有两种类型:常数项(constant member)和计算所得项(computed member)。enumColor{Red,Green,Blue="blue".length};// 常数枚举// 常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员。constenumDirections{Up,Down,Left,Right}letdirections=[Directions.Up,Directions.Down,Directions.Left,Directions.Right];

4. 类

/*  TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public、private 和 protected。 public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的 private 修饰的属性或方法是私有的,不能在声明它的类的外部访问 protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的*/// readonly 只读属性关键字,只允许出现在属性声明或索引签名或构造函数中。classAnimal{// public readonly name;publicconstructor(publicreadonlyname){// this.name = name;}}// 抽象类 abstract 用于定义抽象类和其中的抽象方法。// 1. 不允许被实例化abstractclassAnimal2{publicname;publicconstructor(name){this.name=name;}publicabstractsayHi();}leta=newAnimal2('Jack');// 报错// 2. 抽象类中的抽象方法必须被子类实现abstractclassAnimal3{publicname;publicconstructor(name){this.name=name;}publicabstractsayHi();}// 未实现sayHi方法会报错classCatextendsAnimal3{// public sayHi() {// console.log(`Meow, My name is ${this.name}`);// }}letcat5=newCat('Tom');

5. 类与接口

// 1. 类实现接口 /*  一般来讲,一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口  (interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性 */interfaceAlarm{alert(): void;}classDoor{}classSecurityDoorextendsDoorimplementsAlarm{alert(){console.log('SecurityDoor alert');}}classCarimplementsAlarm{alert(){console.log('Car alert');}}// 一个类可以实现多个接口: class Car implements Alarm, Light// 2. 接口继承接口interfaceLightableAlarmextendsAlarm{lightOn(): void;lightOff(): void;}// 3. 接口继承类// 常见的面向对象语言中,接口是不能继承类的,但是在 TypeScript 中却是可以的:classPoint{x: number;y: number;constructor(x: number,y: number){this.x=x;this.y=y;}}interfacePoint3dextendsPoint{z: number;}letpoint3d: Point3d={x: 1,y: 2,z: 3};

6. 泛型

// 泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。// 我们在函数名后添加了 <T>,其中 T 用来指代任意输入的类型,在后面的输入 value: T 和输出 Array<T> 中即可使用了。functioncreateArray<T>(length: number,value: T): Array<T>{letresult: T[]=[];for(leti=0;i<length;i++){result[i]=value;}returnresult;}createArray<string>(3,'x');// ['x', 'x', 'x']// 1. 定义泛型的时候,可以一次定义多个类型参数:functionswap<T,U>(tuple: [T,U]): [U,T]{return[tuple[1],tuple[0]];}swap([7,'seven']);// ['seven', 7]// 2. 泛型约束// 我们可以对泛型进行约束,只允许这个函数传入那些包含 length 属性的变量。这就是泛型约束:interfaceLengthwise{length: number;}functionloggingIdentity<TextendsLengthwise>(arg: T): T{console.log(arg.length);returnarg;}// 3. 泛型接口interfaceCreateArrayFunc<T>{(length: number,value: T): Array<T>;}letcreateArray1: CreateArrayFunc<any>;createArray1=function<T>(length: number,value: T): Array<T>{letresult: T[]=[];for(leti=0;i<length;i++){result[i]=value;}returnresult;}createArray(3,'x');// ['x', 'x', 'x']// 4. 泛型参数的默认类型functioncreateArray2<T=string>(length: number,value: T): Array<T>{letresult: T[]=[];for(leti=0;i<length;i++){result[i]=value;}returnresult;}

7. 声明合并

// 如果定义了两个相同名字的函数、接口或类,那么它们会合并成一个类型: 合并的属性的类型必须是唯一的interfaceAlarm1{price: number;}interfaceAlarm1{price: number;// 虽然重复了,但是类型都是 `number`,所以不会报错weight: number;}interfaceAlarm2{price: number;}interfaceAlarm2{price: string;// 类型不一致,会报错weight: number;}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions