【Typescript 系列】第四节:extends

123 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

1. 引言

今天我们来介绍类型检测系统中的**“条件类型检测工具”**,它是一种条件表达式进行的关系检测方式。 根据extends不同的使用场景,具有不同的效果。 继承/拓展 约束 分配 接下来我们来介绍当它运用在type和class场景时,分别代表含义。

2. 含义

type 场景 (约束/分配):值 的匹配场景,判断逻辑为是否可被分配,类似JavaScript的三元运算符规则,当值条件规则成功,执行左边,反之,右侧。 class 场景(继承/拓展) :类型继承作用,比如 class A extends class B 就是B类型的属性和方法被A继承拥有。

3. 作用

type 场景下什么叫是否可分配呢?下面我们来举个例子你就知道了

const numVal: number = 2
const numVal2: number = 'zhangsan' // 报错:Type 'string' is not assignable to type 'number'.

在延伸场景中 有一种类似if嵌套判断的方式称之为‘嵌套类型匹配’,请看例子2

假设,当我们在条件类型判断中类型使用的是联合类型 'x' | 'y'又会是怎么样呢,请看例子3 当我们传入联合类型后,对应函数判断返回的也是联合类型,当我们传入T extends U ? 'a' : 'b' 当T为联合类型时,最后的返回类型不仅是联合类型,同时也会触发类型判断“分布式条件类型判断” 官方解释说法:推迟解析条件类型的额外效果,在得知 条件类型不确定时会返回所有的值 的特性情况下,会产生一些额外的效果。

注意: 例子1-4 都是分配,5是约束

4. 例子

例子1// 分配
type IsString<T,U> = T extends U ? true : false
type My1 = IsString<1,string> // ===> false
type My2 = IsString<'1',string> // ===> true
type My3 = IsString<true,false> // ===> false

例子2type TypeName<T> =
    T extends string    ? "string" :
    T extends number    ? "number" :
    T extends boolean   ? "boolean" :
    T extends undefined ? "undefined" :
    T extends Function  ? "function" :
    "object";


type T0 = TypeName<string>;  // "string"
type T1 = TypeName<"a">;     // "string"
type T2 = TypeName<true>;    // "boolean"
type T3 = TypeName<() => void>;  // "function"
type T4 = TypeName<string[]>;    // "object"

例子3type unionFun<T> = T extends 'x' ? 'a' : 'b'
type U1 = unionFun<'y'> // ===> type U1 = "b"
type U2 = unionFun<'x' | 'y'> // ===> type U2 = "a" | "b"

例子4type Itersection<T,U> = T extends U ? U : never
type Difference<T,U> = T extends U ? never : T
type I1 = Itersection<'x' | 'y' | 'z','z'> // ===> type I1 = 'z'
type D1 = Difference<'x' | 'y' | 'z','z'> // ===> type D1 = 'x' | 'y'

例子5// 泛型约束
interface constraint {
  length: number;
}
 
function loggingIdentity<Type extends constraint>(arg: Type): Type {
  console.log(arg.length); // Now we know it has a .length property, so no more error
  return arg;
}

5. 总结

extends 根据使用场景不同,含义也不一样,在使用过程中要区分使用场景。