TypeScript:在 keyof T 处获取属性的类型

Posted

技术标签:

【中文标题】TypeScript:在 keyof T 处获取属性的类型【英文标题】:TypeScript: Getting the type of the property at keyof T 【发布时间】:2021-11-13 18:30:49 【问题描述】:

我在玩 TypeScript 及其打字系统时获得了一些乐趣 - 这并不重要,但也许你们中的一些人会发现这和我一样有趣或有趣。

由于我经常发现自己按所述对象的属性对数组进行排序,所以我想,“为什么不实现 sortBy 函数?”。

Array.prototype.sortBy = function <T, P extends keyof T>(
  this: T[],
  compareFn: (a: unknown, b: unknown) => number,
  key: P
): T[] 
  return this.sort((a, b) => compareFn(a[key], b[key]));
;

用法:

interface A 
  keyA: string;
  keyB: number;

const arr: A[] = [
   keyA: "a", keyB: 42 ,
   keyA: "b", keyB: 1337 ,
   keyA: "c", keyB: -1 ,
];
arr.sortBy((a: number, b: number) => b - a, "keyB");

这个实现是可行的,我认为这很酷,甚至可以将键列表作为类型变量 - 据我所知,例如在 C# 中这种行为是不可能的。

我还想清理最后一件事 - 比较器的 unknown 类型。编译器无法在运行时之前捕获任何可能很危险的错误。是否可以告诉 TS“T 中的属性 P 的类型”?

我想像K extends typeof P in TK extends typeof T[P] 这样的东西。

如果可能的话,我什至可以在函数声明中添加子键,以便按对象树更深处的属性进行搜索。

PS:我知道这是一个相当人为的问题,而且我认为K extends typeof T[P] 在很多情况下根本没有用处。但是玩代码并进行讨论非常有趣,并且加深了对相关语言的理解。

【问题讨论】:

【参考方案1】:

您所要做的就是引用键值:T[P] 请参阅:

Array.prototype.sortBy = function <T, P extends keyof T>(
  this: T[],
  compareFn: (a: T[P], b: T[P]) => number,
  key: P
): T[] 
  return this.sort((a, b) => compareFn(a[key], b[key]));
;

Playground

【讨论】:

哇,我没想到这是可能的!非常感谢!所以我走在了正确的轨道上——我只是没想到我不必创建另一个泛型类型变量^^

以上是关于TypeScript:在 keyof T 处获取属性的类型的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript keyof 和 typeof

[TypeScript] type、typeof、keyof

Typescript 'keyof' 关键字在使用 react setState 函数时出错

TypeScript 中的“keyof typeof”是啥意思?

[TypeScript] Query Properties with keyof and Lookup Types in TypeScript

Type[keyof Type] 函数参数的 Typescript 类型保护