My goal is to add typings for the prop
function. It follows a curried pattern where the key is passed first and the object is passed last.
I attempted an approach where I partially apply it to a key, then try to restrict it to an object containing that property.
This is how I tried to implement it:
const prop = (key: string) =>
<K, T extends { [key: string]: K }>(obj: T): K =>
obj[key]
Unfortunately, this approach doesn't seem to work as expected. For instance, when running this code snippet on TypeScript Playground:
const getFoo = prop('foo')
getFoo({ fooo: 42 })
The error message states:
Error: type '{ fooo: number }' is not assignable to '{ foo: number }'
Vexpected behavior should be an explicit failure instead of failing silently. Also, I expect the type inference to correctly determine the property type in an object. Thus, the following code should fail as intended:
const someNumber: number = prop('foo')({ 'foo': 'abc' })
The error displayed should look like this:
Error: type 'string' is not assignable to 'number'.
This scenario works as designed. However, if I remove the type annotation from someNumber
, the type remains unknown:
const someNumber = prop('foo')({ 'foo': 'abc' })
Is there a way to satisfy all these conditions? I've also considered approaching it "the other way around," by specifying the type of the object we will be working with first and using <T, K extends keyof T>
, but this would require users to provide type parameters each time...