08 - TS infer和强大的类型计算体系

#### 类型计算

Typescript的强大类型计算能力

Typescript 提供了一系列强大的类型计算能力。

联合类型

// 联合类型可以让你允许一个值是几种类型之一。
type Shape = Cirle | Rect | Triangle;

求并集类型

type A = { a : number, b : number }
type B = { a : number, c : number }
type C = A & B
// 结果是 C 类型为 {a : number, b : number , c : number}

接口的联合

// 当一个类实现一个接口时,它必须满足接口的所有要求。
interface A {
   foo() : void
}

interface A {
   bar() : void
}

class X implements A {
   foo(){

   }
}

// ERROR: 这个类没有正确地实现接口A,因为它缺少了'bar'方法。

更复杂的`infer`

// infer是Typescript中的一个关键字,它在类型中进行类型推导。
function flattern(arr){
    
}
// 如何为这个函数提供一个更准确的类型呢?

可以使用数组的any类型,但这并不理想

function flattern(arr : Array<any>) : Array<any> {
    
}

使用infer进行类型推导

// infer关键字可以告诉typescript去推导一个类型
type Flatterned<T> = T extends (infer V)[] ? V : T

类型提取

// 使用infer,我们可以从其他类型中提取类型。
type Unwrapped<T> =  T extends (infer U)[] ? U : T

function first<T>(arr : Array<T>) : Unwrapped<Array<T>> {
   return arr[0]
}

从Promise中提取类型

// 思考一下:如何从Promise<string>[]中提取string[]?
type Unwrap<T> = T extends Promise<infer U> ? Unwrap<U> 
   : T extends Array<infer V> ?
      UnwrapArray<T> :
   T

type UnwrapArray<T> = T  extends Array<infer R>
   ? { [P in keyof T] : Unwrap<T[P]> }
   : T

type T0 = Unwrap<Promise<Promise<number>>[]>

Vue Reactivity 源码解读(类型部分)

// Vue的响应性系统在其源代码中使用了许多高级的类型技巧。
import {UnwrapRef, reactive, ref, Ref} from 'vue'
type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRef<T>

总结

Typescript的类型系统是非常强大的,通过使用联合类型、类型推导和其他高级特性,你可以创建非常复杂和强大的类型。

posted on 2022-03-08 18:51  完美前端  阅读(359)  评论(0)    收藏  举报

导航