用于从 Typescript 中的对象中提取 属性 的类型安全柯里化函数

Type-safe curried function for extracting property from object in Typescript

我想为我的 prop 函数添加类型。它是柯里化的(键在前,对象在后)。

我尝试了以下方法:将它部分应用于某个键后,我尝试将其限制为包含这样一个 属性.

的对象

我尝试通过以下方式实现它:

const prop = (key: string) =>
  <K, T extends { [key: string]: K }>(obj: T): K =>
  obj[key]

不幸的是,这种方法似乎行不通。这是我预计会失败的代码(我还在 a Typescript Playground 中包含了所有这些代码):

const getFoo = prop('foo')
getFoo({ fooo: 42 })

错误信息如

Error: type '{ fooo: number }' is not assignable to '{ foo: number }'

然而事实并非如此(它默默地失败了)。 我还希望推断对象中 属性 的类型,所以这段代码失败了:

const someNumber: number = prop('foo')({ 'foo': 'abc' })

错误如:

Error: type 'string' is not assignable to 'number'.

这是按预期工作的。但是,如果我在 someNumber 上省略类型注释,则不会进行推断,因此对于:

const someNumber = prop('foo')({ 'foo': 'abc' })

someNumber 的类型未知。 有没有办法满足所有这些限制?

我也一直在考虑这样做"the other way around",首先给出我们将要处理的对象的类型,然后再用<T, K extends keyof T>做一些事情,但这会迫使用户每次都提供类型参数...

试试这个:

const prop = <Key extends string>(key: Key) =>
  <T extends Record<Key, any>>(obj: T): T[Key] =>
  obj[key];

const getFoo = prop('foo')
const result: string = getFoo({ foo: 42 })

我设法使用 mapped types 开发解决方案:

const prop = <K extends string>(key: K) =>
  <T extends { [k in K]: T[K] }>(obj: T): T[K] =>
  obj[key];

Link 到 Typescript Playground