用于从 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
我想为我的 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