类型操作之Conditional Type

398 阅读1分钟

TS:类型操作.png

Conditional

基础用法

条件类型类似js中三元运算符 ,即

SomeType extends OtherType ? TrueType : FalseType;
  • 基础使用:
interface Animal {
  live(): void;
}
interface Dog extends Animal {
  woof(): void;
}
type Example1 = Dog extends Animal ? number : string;//type Example1 = number
type Example2 = RegExp extends Animal ? number : string;//type Example2 = string

在此处对extents的理解如下,A extends B,是指类型A可以分配给类型B,而不是说类型A继承了类型B,即A的范围比B小,则为true

type Duck = {
  name: string;
}
type Cat = {
  name: string;
}
type Bool1 = Duck extends Cat ? 'yes' : 'no'; // Bool1 => 'yes'
// Duck的类型可以分配给Cat,因此是'yes'
type Human = {
  name: string;
  occupation: string;
}
type Bool2 = Human extends Duck ? 'yes' : 'no'; // Bool2 => 'yes'
//可以理解为满足Human的都满足Duck,即Human就可以分配给Duck,
type Bool3 = Duck extends Human ? 'yes' : 'no'; // Bool3 => 'no'type Bool4 = never extends Human ? 'yes' : 'no'; // Bool4 => 'yes'
//never的特殊性

extends

extends在ts中除用于conditional type中之外,还有另外两种用法:继承、泛型约束

  • 继承
// Dog => { name: string; bark(): void }
interface Animal {
    kind: string;
}
interface Dog extends Animal {
  bark(): void;
}
  • 泛型约束

    在书写泛型的时候,对类型参数作一定的限制,比如希望传入的参数都有 name 属性的数组我们可以这么写:

//extends对传入的参数作了一个限制,就是entities必须含有类型为string的name属性
function getCnames<T extends { name: string }>(entities: T[]):string[] {
  return entities.map(entity => entity.name)
}

infer用法

表示在 extends 条件语句中待推断的类型变量,简单示例:

type ParamType<T> = T extends (...args: infer P) => any ? P : T;

又如以下两种写法意思相同,

//使用索引访问
type Flatten<T> = T extends any[] ? T[number] : T;
​
//使用infer的写法
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;