在TypeScript中使用类型泛型扩展一个类型

14
在某些情况下,我想扩展字面上被转换(使用“as const”)的对象的类型,以便它的属性将被推断为字符串或数字,而不是字面意义上的值。
假设我有以下类型:
const obj = [
   {
      type:"student", 
      name:"Yossi"
   }, 
   {
      type: "Teacher", 
      name: "Lili"
   }
] as const

type Person = typeof obj [number]
我希望对象的类型能够被直接推断出来,但是人类类型需要更加广泛,这样它的类型和名称就成为字符串。是否有一个通用方法可以允许以下操作:
type Person = Widen<typeof obj [number]>

不太可能。使用情况是什么?实际上,每个属性只有两个可能的值。TypeScript 推断出了一个狭窄的类型,这是正确的。 - Madara's Ghost
@MadaraUchiha,我想要一个组件(函数),它可以接受并专门处理学生和教师,因此只能接受obj的值,还有另一个更广泛的组件/函数,可以接受任何职业的人。 - Ben Carp
1
可能是https://dev59.com/mrTma4cB1Zd3GeqP1iKI的重复问题。 - jcalz
3
我修改“widden”为“widen”,有人介意吗? - jcalz
2
@jcalz,我已经修复了。不过,我不是以英语为母语的人,所以请随时纠正或提供建议。 - Ben Carp
1个回答

16

有趣的案例。我们可以通过映射类型来尝试创建这样的实用程序。考虑以下内容:

// 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 Widen<O> = {
  [K in keyof O]: ToPrimitive<O[K]>
}
// using
type Person = Widen<typeof obj[number]>
const a: Person = {
  name: 'name', // string
  type: 'type' // string
}


我们可以通过添加额外的条件,将ToPrimitive扩展到考虑其他类型,如对象、数组等。
根据我所看到的,您的元素obj在原始类型方面只有一个 - {name: string, type: string}。然后我们可以通过以下方式从第一个元素创建一个类型:
type Person = Widen<typeof obj[0]>;
// and this nicely evaluates to:
type Person = {
    readonly type: string;
    readonly name: string;
}

我们可以通过添加额外的条件来扩展ToPrimitive以考虑其他类型,如对象、数组。在保留类型安全性的同时,如何在嵌套对象中实现这一点? - old greg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接