微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

TypeScript:从对象值派生的动态联合类型

如何解决TypeScript:从对象值派生的动态联合类型

我想从一个类似表格的输入对象派生一个联合类型。我已经成功地解决一个可行的解决方案,但我认为应该有更短/更直接的方法。这是输入对象:

const _COLUMNS = {
  "id": {sortable: true},// more Metadata in real code
  "@fullname": {sortable: true},"@profiles": {sortable: false},"created_at": {sortable: false},...
} as const

这是我的解决方案:

type Column = keyof (typeof _COLUMNS)

// ---
type FindSortable<K extends string,T extends {sortable : boolean}> = T extends {sortable : true} ? K : never

type _Sortable = {
  [K in Column] : MakeSortable<K,typeof _COLUMNS[K]>
}

type Sortable = _Sortable[keyof _Sortable] // "id" | "@fullname"
type Order = `${Sortable}:${"asc" | "desc"}` // "id:asc" | "id:desc" | ...
//---

有没有办法在没有中间人 Sortable 的情况下定义上述动态 _Sortable 类型?这是重复结构:

type Sortable = 
  | FindSortable<"id",typeof _COLUMNS["id"]>
  | FindSortable<"@fullname",typeof _COLUMNS["@fullname"]>
  ...
  | FindSortable<K,typeof _COLUMNS[K]> ??

或者用类似数学的符号:

type Sortable = FindSortable<K,typeof _COLUMNS[K]> ∀ K in Column ??

解决方法

是的,您可以立即从 _Sortablelook up 映射类型的属性值,而不是将其分配给新的类型别名:

type Sortable = {
  [K in Column]: FindSortable<K,typeof _COLUMNS[K]>
}[Column]

我不知道为什么消除 _Sortable 很重要,但是如果您不想定义 FindSortable 甚至 Column,您可以在单个类型别名中完成所有操作:

type Sortable = typeof _COLUMNS extends infer C ?
  keyof C extends infer K ?
  K extends keyof C ?
  C[K] extends { sortable: true } ?
  K : never : never : never : never;

// type Sortable = "id" | "@fullname"

但这只是愚蠢的?。

Playground link to code

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。