# Previously

class Fruit {
	name: string;
	color: string;
}

class Apple extends Fruit {
	// bla bla
}
1
2
3
4
5
6
7
8

Class 可以通过 extends 关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。More Info (opens new window)

# 定义 Typescript extends 关键字

extends

可以用来继承一个类,也可以用来继承一个 interface,但还可以用来判断有条件类型,接口支持多重继承,语法为逗号隔开

# 使用

# 条件类型

Typescript 2.8 新增 (opens new window) extends 用来条件类型判断。

:::tips 表示条件判断,如果前面的条件满足,则返回问号后的第一个参数,否则第二个。类似于js的三元运算。 :::

T extends U ? X : Y
1

上面的类型表示当 T 可分配给 U 时,类型为 X,否则为 Y

原理是令 T'U' 分别为 TU 的实例,并将所有类型参数替换为 any,如果 T' 能赋值给 U',则将有条件的类型解析成 X,否则为Y

// Remove types from T that are assignable to U ===> 差集
type Diff<T, U> = T extends U ? never : T;
// Remove types from T that are not assignable to U ===> 交集
type Filter<T, U> = T extends U ? T : never;

type T1 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">;
//   ^ = type T1 = "b" | "d"
type T2 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c"
//   ^ = type T2 = "a" | "c"
type T3 = Diff<string | number | (() => void), Function>; // string | number
//   ^ = type T3 = string | number
type T4 = Filter<string | number | (() => void), Function>; // () => void
//   ^ = type T4 = () => void
1
2
3
4
5
6
7
8
9
10
11
12
13

T 是联合类型时,

(T1 | T2) extends U ? X : Y
 
 // (T1 extends U | T2 extends U) ? X : Y
1
2
3

# 继承

像类一样,接口可以互相扩展。 这使您可以将一个接口的成员复制到另一个接口中,从而在如何将接口分离为可重用组件方面提供了更大的灵活性。

interface Shape {
  color: string;
}

interface Square extends Shape {
  sideLength: number;
}

let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
1
2
3
4
5
6
7
8
9
10
11

一个接口可以扩展多个接口,从而创建所有接口的组合。

interface Shape {
  color: string;
}

interface PenStroke {
  penWidth: number;
}

interface Square extends Shape, PenStroke {
  sideLength: number;
}

let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 类继承

interface Profile {
  name: string;
  age?: string | number;
}

class Person {
  name: string;
  age?: string | number;
  
  constructor(options: Profile) {
    this.name = options?.name;
    this.age = options?.age;
  }
}

 class Boy extends Person {
   gender: string
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 快来耍耍啊

# 🌰🌰

// template
1

# 游乐场


# 参考答案

// answer
1

# 参考资料

conditional-types (opens new window)

extending-interfaces (opens new window)

whats-the-difference-between-extends-and-implements-in-typescript (opens new window)