条件类型,子类型 extends 父类型
// 通常和类型约束一起使用,类似三元运算符,条件类型只能在 type 中使用
type ResStatusMessage<T extends number> = T extends 200 | 201 | 202 ? "success" : "fail"
let result:ResStatusMessage<200> = "success"
<T extends number> 约束泛型传参
T extends 200 | 201 | 202 ? "success" : "fail" 约束返回值
type Conditional<T, U> = T extends U ? "success" : "fail"
let condition:Conditional<'test',string> = "success"
- 通过条件类型,实现约束的效果
interface Bird {
name: "鸟"
}
interface Fish {
name: "鱼"
}
interface Sky {
name: "天空"
}
interface Water {
name: "水"
}
type Conditional<T extends Fish | Bird> = T extends Bird ? Sky : Water
type conditional = Conditional<{ // Sky
name: "鸟",
height: 100
}>
// 三元嵌套
type Conditional<T extends string | number> = T extends string ? string : T extends number ? number : never
- 条件分发
产生条件:
1. A类型通过泛型传入
type conditional = string | number extends string ? string : number // number 不满足,因为不是泛型传入,没有产生分发
2. 比较(extends)的时候会产生分发
3. 泛型参数A 必须是完全裸露的(只有泛型,没有和别人搭配)T 是泛型,但是 T[]或者 [T]就不是单独的泛型了
type conditional<T> = T extends string ? string : number // 不满足,因为不是泛型传入,没有产生分发
// 将联合类型中的每一项单独的进行比较
type c1 = conditional<string | number> // string | number
// 条件分发
// conditional<string> -> string
// conditional<number> -> number
type conditional<T, U> = T extends U ? true : false
type R1 = conditional<1 | 2, 1 | 2 | 3> // true
// conditional<1> -> true
// conditional<2> -> true
type conditional<T, U> = T extends U ? true : false
type R1 = conditional<1 | 2, 1> // boolean
// conditional<1> -> true
// conditional<2> -> false
// 分发就是挨个比较,不想分发就是将结果运算后再比较
// 只要让 A 不是裸类型,就禁用分发
type conditional<T, U> = T & {} extends U ? true : false // T & {} 不是泛型裸类型,阻止分发。T & {}还是T,只是为产生一个新类型。
type R1 = conditional<1 | 2, 1> // false
或者
type conditional<T, U> = [T] extends [U] ? true : false // T & {} 不是泛型裸类型,阻止分发
type R1 = conditional<1 | 2, 1> // false
// 特例
type conditional<T> = T extends never ? true : false
type r1 = conditional<never> // never, never直接比较的时候,无法返回正确的结果
type conditional<T> = [T] extends [never] ? true : false
type r1 = conditional<never> // true
type conditional<T> = T & {} extends never ? true : false
type r1 = conditional<never> // true