Skip to content

TypeScript 中的 extends 关键字

extends 关键字在 TypeScript 中经常用到,在不同场景下含义不同,总结如下:

1 表示继承

继承父类的方法和属性

Class 可以通过 extends 关键字实现继承

js
class Animal {
  public name;
  constructor(name) {
    this.name = name;
  }
  sayHi() {
    return `My name is ${this.name}`;
  }
}

class Cat extends Animal {
  public color;
  constructor(color) {
    this.color = color;
  }
}

let c = new Cat('Tom');
console.log(c.sayHi()); // Meow, My name is Tom

继承某个类型

js
 interface Animal {
   kind: string;
 }
 
 interface Dog extends Animal {
   bark(): void;
 }
 // Dog => { name: string; bark(): void }

2 泛型约束

Constraints

约束(Constraints)

TypeScript 泛型参数的默认值理解

Generic parameter defaults

在书写泛型的时候,我们往往需要对类型参数作一定的限制,比如希望传入的参数是一个对象数组,且数组的每一项是至少含有 name 属性(类型为 string),我们可以这么写:

js
function getCnames<T extends { name: string }>(entities: T[]): string[] {
  return entities.map(entity => entity.name)
}

T extends A 表示用类型 A 对类型 T 进行约束,若类型 A 有 n 个约束条件,那么类型 T 至少也有这 n 个约束条件。

T extends { name: string, age: number } 表示 T 是一个对象,且至少含有属性name(类型为 string)、age(类型为 number),T 可以还包含其他属性。

3 条件类型

SomeType extends OtherType ? TrueType : FalseType;

条件类型有点像 JavaScript 中的三元表达式,当左侧的类型符合右侧类型“约束”时,将在第一个分支(“真实”分支)中获得类型;否则,将在后一个分支(“假”分支)中获得类型。

js
interface Animal {
  live(): void;
}
interface Dog extends Animal {
  woof(): void;
}
 
// Animal 表示需要有属性 live,而 Dog 有属性 live、woof,所以这里符合约束(套用“泛型约束”)
type Example1 = Dog extends Animal ? number : string;  // type Example1 = number
 
type Example2 = RegExp extends Animal ? number : string;  // type Example2 = string
js
type Human = {
  name: string;
  occupation: string;
}
type Duck = {
  name: string;
}
type Bool = Duck extends Human ? 'yes' : 'no'; // type Bool = 'no'

可以发现此时类型 Bool 为 'no',这是因为 Duck 没有类型为 string 的 occupation 属性,类型 Duck 不满足类型 Human 的约束条件

Duck extends Human 中 Human 约束了 Duck,表示 Duck 需要满足条件 “有两个属性name、Duck,且都是 string 类型”(这跟泛型约束是一致的),如果满足就取“真”类型,否则取“假”类型

js
type Human = {
  name: string;
}
type Duck = {
  name: string;
  occupation: string;
}
type Bool = Duck extends Human ? 'yes' : 'no'; // type Bool = 'yes'