类型别名

类型别名用来给一个类型起个新名字,类型别名常用于联合类型

  1. type Name = string;
  2. type NameResolver = () => string;
  3. type NameOrResolver = Name | NameResolver;
  4. function getName(n: NameOrResolver): Name {
  5. if (typeof n === 'string') {
  6. return n;
  7. } else {
  8. return n();
  9. }
  10. }

上例中,我们使用 type 创建类型别名

字符串字面量类型

字符串字面量类型用来约束取值只能取三种字符串中的一种

  1. type EventNames = 'click' | 'scroll' | 'mousemove';
  2. function handleEvent(ele: Element, event: EventNames) {
  3. // do something
  4. }
  5. handleEvent(document.getElementById('hello'), 'scroll'); // 没问题
  6. handleEvent(document.getElementById('world'), 'dblclick'); // 报错,event 不能为 'dblclick'
  7. // index.ts(7,47): error TS2345: Argument of type '"dblclick"' is not assignable to parameter of type 'EventNames'.

上例中,我们使用type定了一个字符串字面量类型EventNames,它只能取三种字符串中的一种。
注意:类型别名字符串字面量类型都是使用type进行定义的。

元组

数组合并了相同类型的对象,而元组合并了不同类型的对象

  1. // 定义一对值分别为string和number的元组
  2. let tom: [string, number] = ['Tom', 25];
  3. // 元组里元素和声明的类型要一一对应
  4. let jack: [string, number] = [26, 'jack']; // 报错

在赋值的时候也需要和声明的时候对应

  1. let tom: [string, number];
  2. tom = ['Tom'];
  3. // Property '1' is missing in type '[string]'
  4. but required in type '[string, number]'.

元组每个位置数据类型必须一一对应,且不能空着;如果不想这样可以这样声明

  1. let arr: Array<number | string> = ['1', 2, 3]

枚举

枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。
枚举使用 enum 关键字来定义:

  1. enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }

枚举成员会被赋值从0开始递增的数字,同时也会对枚举值到枚举名进行反向映射

  1. enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
  2. console.log(Days["Sun"] === 0); // true
  3. console.log(Days["Mon"] === 1); // true
  4. console.log(Days["Tue"] === 2); // true
  5. console.log(Days["Sat"] === 6); // true
  6. console.log(Days[0] === "Sun"); // true
  7. console.log(Days[1] === "Mon"); // true
  8. console.log(Days[2] === "Tue"); // true
  9. console.log(Days[6] === "Sat"); // true

手动赋值

  1. enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
  2. console.log(Days["Sun"] === 7); // true
  3. console.log(Days["Mon"] === 1); // true
  4. console.log(Days["Tue"] === 2); // true
  5. console.log(Days["Sat"] === 6); // true

public、private和protected

  • public哪里都可以访问
  • private私有属性,不能在类外部访问,不能继承
  • protect也不能在类外部访问,但可以继承 ```typescript class Animal { public name; public constructor(name) { this.name = name; } }

let a = new Animal(‘Jack’); console.log(a.name); // Jack a.name = ‘Tom’; console.log(a.name); // Tom

  1. // 当name为私有属性时,不能再外部直接访问
  2. ```typescript
  3. class Animal {
  4. private name;
  5. public constructor(name) {
  6. this.name = name;
  7. }
  8. }
  9. let a = new Animal('Jack');
  10. console.log(a.name); // Jack
  11. a.name = 'Tom';
  12. // index.ts(9,13): error TS2341: Property 'name' is private and only accessible within class 'Animal'.
  13. // index.ts(10,1): error TS2341: Property 'name' is private and only accessible within class 'Animal'.

抽象类

不允许被实例化,里面的方法必须被继承的子类来实现

下面这种情况就是子类没有实现抽象类的抽象方法sayHi从而引起的报错

  1. abstract class Animal {
  2. public name;
  3. public constructor(name) {
  4. this.name = name;
  5. }
  6. public abstract sayHi();
  7. }
  8. class Cat extends Animal {
  9. public eat() {
  10. console.log(`${this.name} is eating.`);
  11. }
  12. }
  13. let cat = new Cat('Tom');
  14. // index.ts(9,7): error TS2515: Non-abstract class 'Cat' does not implement
  15. inherited abstract member 'sayHi' from class 'Animal'.

泛型

泛型是指在定义函数、接口或类的时候,不预先指定具体类型,而在使用的时候再指定类型的一种特性。
不好的实例写法

  1. function createArray(length: number, value: any): Array<any> {
  2. let result = [];
  3. for (let i = 0; i < length; i++) {
  4. result[i] = value;
  5. }
  6. return result;
  7. }
  8. createArray(3, 'x'); // ['x', 'x', 'x']

上面的这段代码不会报错,但是一个显而易见的缺陷是,它并没有准确的定义返回值的类型;
Array允许数组的每一项都为任意类型。但是我们的预期是,数组中每一项都应该是输入的value类型。这时候泛型就派上用场了:

  1. function createArray<T>(length: number, value: T): Array<T> {
  2. let result: T[] = [];
  3. for (let i = 0; i < length; i++) {
  4. result[i] = value;
  5. }
  6. return result;
  7. }
  8. createArray<string>(3, 'x'); // ['x', 'x', 'x']
  9. // 也可以 createArray(3, 'x');这样调用,让类型推论自动推算出来

函数名后添加了,其中T用来指代任意输入的类型,在后面的输入value: T和输出Array中即可使用了。