使用Typescript中的泛型类型加宽类型

时间:2019-12-16 11:08:07

标签: typescript

在某些情况下,我想确定按字面类型转换的对象的类型(使用“ as const”),因此将其属性推断为字符串或数字,而不是字面值。

想象一下我有以下类型

const obj = [
   {
      type:"student", 
      name:"Yossi"
   }, 
   {
      type: "Teacher", 
      name: "Lili"
   }
] as const

type Person = typeof obj [number]

我希望从字面上推断obj的类型,但希望Person更宽,因此类型和名称都是字符串。是否有通用名称可以允许以下内容:

type Person = Widden<typeof obj [number]>

2 个答案:

答案 0 :(得分:5)

有趣的情况。我们可以尝试通过映射类型创建此类实用程序。考虑:

// it transforms our specific types into primitive origins
type ToPrimitive<T> =
  T extends string ? string
  : T extends number ? number
  : T extends boolean ? boolean
  : T;
// mapped types which will preserve keys with more wide value types
type Widden<O> = {
  [K in keyof O]: ToPrimitive<O[K]>
}
// using
type Person = Widden<typeof obj[number]>
const a: Person = {
  name: 'name', // string
  type: 'type' // string
}

我们可以通过添加其他条件来扩展ToPrimitive以考虑其他类型,例如对象,数组。

正如我所见,您的obj类型的元素在术语或原始类型中是-{name: string, type: string}。然后我们可以通过以下方式从第一个元素创建类型:

type Person = Widden<typeof obj[0]>;
// and this nicely evaluates to:
type Person = {
    readonly type: string;
    readonly name: string;
}

答案 1 :(得分:1)

  

我希望有一个组件(功能)可以接受并专门处理学生和教师,而另一个组件/功能则更广泛,可以接受任何人,无论其专业是什么。

在这里改用discriminated unions怎么办?

dropins

Playground