Appearance
extends
主要作用:
- 继承(JS 中 Class 的 extends 一样)
- 泛型约束
- 条件分配
继承
- 配合 Class 使用,跟 Java 中的 Class 的继承很像。主要是继承父类的公共方法 和 公共属性
ts
class Animal {
name: string
constructor() {}
sayName() {
console.log(this.name)
}
}
class Dog extends Animal {} // 继承的作用
- 接口的继承
ts
interface PaginationCommonRequest {
pageSize: number
current: number
}
// GetUserPageRequest === { current: number; pageSize: number; name?: string; }
interface GetUserPageRequest extends PaginationCommonRequest {
name?: string
}
// 也可以重写某一个属性
// IPaginationCommonRequest === { current: string; pageSize: number; }
interface IPaginationCommonRequest extends PaginationCommonRequest {
current: string
}
泛型约束
主要在我们使用泛型的时候,希望传入的泛型必须包含某一个或者多个特定的属性,这时候就可以使用 extends
ts
// T extends { current: number }
function getPaginationCurrent<T extends { current: number }>(pagination: T): number {
return pagination.current
}
getPaginationCurrent({ current: 1, pageSize: 10 })
getPaginationCurrent({ pageSize: 1 })
在上述例子中 T extends { current: number }
就起到泛型约束的作用,即限制传入的入参 T 必须包含 current 属性
条件分配
对于条件分配很像我们三目运算符,作用也很像
ts
T extends U ? T : U
T 是 U 的一个子集那就返回 T,不然返回 U
- 类型判断
- 接口类型
对于接口,extends 判断的是所有的属性是否相同
ts
interface Pagination {
pageSize: number
current: number
total: number
pageNumber: number
}
interface PaginationRequest {
pageSize: number
current: number
}
interface IPaginationRequest {
pageSize: number
current: number
}
type Bool = PaginationRequest extends Pagination ? true : false // false
type Bool1 = IPaginationRequest extends PaginationRequest ? true : false // true
- type 类型
对于 type,extends 判断的是是否是联合类型的子集
ts
type User = "Admin" | "TL" | "SEAT"
type ConsoleUser = "TL" | "SEAT"
type Bool1 = ConsoleUser extends User ? true : false // true
- never
never 是一个特殊的类型,其是所有其他类型的子集,所以
ts
type Bool2 = never extends Pagination ? true : false // true
type Bool3 = never extends number ? true : false // true
type Bool4 = never extends never ? true : false // true
- Exclude、Extract、Pick
使用 extends 的条件判断和 never,我们就可以自定义内置的高级类型 Exclude、Extract、Pick
- Exclude
从 T 中剔除可以赋值给 U 的类型
ts
type Exclude<T, U> = T extends U ? never : T
其中我们有一个特殊的疑惑?
ts
type Exclude1<T, U> = T extends U ? never : T
type IType = "name" | "age" | "address"
type IType2 = "name" | "age" | "sex"
type A = IType extends IType2 ? never : IType // "name" | "age" | "address"
type B = Exclude1<IType, IType2> // "address"
为什么A 和 B的结果是不一样的?
网上有一种解释
ts
type B = Exclude1<IType, IType2> // "address"
// ===
type B = "name" extends IType2 ? never : "name" | "age" extends IType2 ? never : "age" | "address" extends IType2 ? never : "address"