【问题标题】:how to get Type from object value如何从对象值中获取类型
【发布时间】:2021-11-12 19:43:10
【问题描述】:
const arr=[{type:'a'},{type:'b'}]

type TypeFromVal<T>=T extends {type:infer R}[]?R:any

function GetType<T extends {type:string}[]>(arr:T,type:TypeFromVal<T>){
 return arr.find(item=>item.type===type).type
}

GetType(arr,0)

自动推断是字符串或数字,我想得到类型是 'a'|0 我想 Typescript 知道从 arr 推断的函数参数类型。 也就是说,如何从 infer 中获取类型?

【问题讨论】:

    标签: javascript typescript tuples type-inference typescript-generics


    【解决方案1】:

    为了推断所有类型,您应该将as const 用于arr,或者将其作为文字类型传递给函数而不是传递引用。

    type FindIndex<
      T extends Array<{ type: string }>,
      ExpectedType extends T[number]['type'],
    
      > = {
        [Prop in keyof T]:
        (T[Prop] extends { type: infer Type }
          ? (Type extends ExpectedType
            ? Prop
            : never
          )
          : never
        )
      }[number];
    {
      // 0
      type Test = FindIndex<[{ type: 'a' }, { type: 'b' }], 'a'>
    }
    
    function GetType<
      Type extends string,
      Elem extends { type: Type },
      Arr extends Elem[],
      ExpectedType extends Arr[number]['type'],
      >(arr: [...Arr], type: ExpectedType): FindIndex<Arr, ExpectedType>
    function GetType<
      Arr extends { type: string }[],
      ExpectedType extends Arr[number]['type'],
      >(arr: [...Arr], type: ExpectedType) {
      return arr.find((item) => item.type === type)
    }
    
    const result = GetType([{ type: 'a' }, { type: 'b' }], 'a') // 0
    

    说明

    FindIndex - 遍历文字推断的元组/数组并检查type 属性是否扩展ExpectedType。如果是 - 返回Prop,在我们的例子中这是一个索引。否则 - never。所以,如果最后没有[number],你最终会得到[0, never]。通过[number] 对其进行索引返回0 | never,它基本上等于0

    我已经超载了GetType 以应用FindIndex

    另外,您可能已经注意到,为了推断字面量类型,您应该推断元素的每个属性。你应该从下往上走。

    第一个通用 Type 推断 type 属性。然后,Elem 推断 数组的每个元素。最后Arr,感谢variadic tuple types 被完全推断出来。

    您可以在我的博客here 和类型推断here 中找到有关元组操作的更多信息

    【讨论】:

    • 谢谢一百万。你太棒了。
    【解决方案2】:
    const arr = [{type: 'a'}, {type: 'b'}];
    
    type TypeFromVal = {
      type: string | number
    }
    
    function GetType(arr: Array<TypeFromVal>, type: number | string) {
      return arr.find(item => item.type === type)?.type
    }
    
    console.log(GetType(arr, 0));
    

    【讨论】:

    • 这不是我的意图。我希望​​从 arr 获取类型并带有 typescript 提示
    • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
    • 非常简单
    猜你喜欢
    • 1970-01-01
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 2014-01-07
    • 2016-10-07
    • 2017-01-01
    相关资源
    最近更新 更多