zoukankan      html  css  js  c++  java
  • typescript 中的 infer 关键字的理解

    infer 这个关键字,整理记录一下,避免后面忘记了。有点难以理解呢。

    infer

    infer 是在 typescript 2.8中新增的关键字。

    infer 可以在 extends 条件类型的字句中,在真实分支中引用此推断类型变量,推断待推断的类型。

    例如:用infer推断函数的返回值类型

    type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
    
    type fn = () => number
    type fnReturnType = ReturnType<fn> // number
    

    在这个例子中,

    T extends U ? X : Y的形式为条件类型。

    infer R代表待推断的返回值类型,如果T是一个函数(...args: any[]) => infer R,则返回函数的返回值R,否则返回any

    案例:加深理解

    反解 Promise

    // promise 响应类型
    type PromiseResType<T> = T extends Promise<infer R> ? R : T
    
    // 验证
    async function strPromise() {
      return 'string promise'
    }
    
    interface Person {
      name: string;
      age: number;
    }
    async function personPromise() {
      return {
        name: 'p',
        age: 12
      } as Person
    }
    
    type StrPromise = ReturnType<typeof strPromise> // Promise<string>
    // 反解
    type StrPromiseRes = PromiseResType<StrPromise> // str
    
    type PersonPromise = ReturnType<typeof personPromise> // Promise<Person>
    // 反解
    type PersonPromiseRes = PromiseResType<PersonPromise> // Person
    

    反解函数入参类型

    type Fn<A extends any[]> = (...args: A) => any
    type FnArgs<T> = T extends Fn<infer A> ? A : any
    
    function strFn (name: string) {
    
    }
    
    type StrFn = FnArgs<typeof strFn> // [string]
    

    tuple 转 union ,如:[string, number] -> string | number

    type ElementOf<T> = T extends Array<infer E> ? E : never
    
    type TTuple = [string, number];
    
    type ToUnion = ElementOf<ATuple>; // string | number
    

    new 操作符

    // 获取参数类型
    type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
    
    // 获取实例类型
    type InstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer R ? R : any;
    
    class TestClass {
    
      constructor(
        public name: string,
        public string: number
      ) {}
    }
    
    type Params = ConstructorParameters<typeof TestClass>;  // [string, numbder]
    
    type Instance = InstanceType<typeof TestClass>;         // TestClass
    

    react - reducer

    // 定义
    function useReducer<R extends Reducer<any, any>, I>(
      reducer: R,
      // ReducerState 推断类型
      initializerArg: I & ReducerState<R>,
      initializer: (arg: I & ReducerState<R>) => ReducerState<R>
    ): [ReducerState<R>, Dispatch<ReducerAction<R>>];
    
    // infer推断
    type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any>
      ? S
      : never;
    // Reducer类型
    type Reducer<S, A> = (prevState: S, action: A) => S;
    
    
    // 使用 reducer
    const reducer = (x: number) => x + 1;
    const [state, dispatch] = useReducer(reducer, '');
    // Argument of type "" is not assignable to parameter of type 'number'.
    

    vue3 - ref

    export interface Ref<T = any> {
      [isRefSymbol]: true
      value: T
    }
    
    export function ref<T>(value: T): T extends Ref ? T : Ref<UnwrapRef<T>>
    
    export type UnwrapRef<T> = {
      cRef: T extends ComputedRef<infer V> ? UnwrapRef<V> : T
      ref: T extends Ref<infer V> ? UnwrapRef<V> : T
      array: T
      object: { [K in keyof T]: UnwrapRef<T[K]> }
    }[T extends ComputedRef<any>
      ? 'cRef'
      : T extends Array<any>
        ? 'array'
        : T extends Ref | Function | CollectionTypes | BaseTypes
          ? 'ref' // bail out on types that shouldn't be unwrapped
          : T extends object ? 'object' : 'ref']
    
    
    // 使用
    const count = ref({
      foo: ref('1'),
      bar: ref(2)
    })
    
    // 推断出
    const count: Ref<{
      foo: string;
      bar: number;
    }>
    
    const count = ref(2) // Ref<number>
    
    const count = ref(ref(2)) // Ref<number>
    
    

    参考

  • 相关阅读:
    任务二 发布作业信息(已完成)
    查看作业信息(任务一 已完成)
    项目冲刺任务之任务场景分析(四)
    项目冲刺之任务场景分析(三)
    解析XML文件的两种方式 SAX和DOM
    解析XML文件的两种方式 SAX和DOM
    iOS开发代码规范(通用)
    随机创建点击对象
    自定义加载等待框(MBProgressHUD)
    KVO、KVC
  • 原文地址:https://www.cnblogs.com/EnSnail/p/14938799.html
Copyright © 2011-2022 走看看