如何从对象值中获取类型

how to get Type from object value

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 我想打字稿知道从 arr 推断的函数参数类型。 换句话说,如何从推断中获取类型?

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));

为了推断所有类型,您应该将 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 - 迭代字面推断 tuple/array 并检查 type 属性 是否扩展 ExpectedType。如果是 - return Prop,在我们的例子中这是一个索引。否则 - never。因此,如果末尾没有 [number],您将得到 [0, never]。通过[number] returns 0 | never对其进行索引,基本上等于0.

我已超载 GetType 以应用 FindIndex

此外,您可能已经注意到,为了推断文字类型,您应该推断元素的每个属性。你应该从底部到顶部。

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

您可以在我的博客中找到有关元组操作的更多信息here and about type inference here