[英]Why does this TS implementation of "prop" work but mine does not?
I was looking through some blogs about how to use the keyof
feature of typescript to implement a classic function in Ramda/Underscore called prop
which returns the value corresponding to a given key on a certain object.我正在浏览一些关于如何使用keyof
功能在keyof
中实现一个名为prop
的经典函数的博客,该函数返回与某个对象上的给定键对应的值。
Example:例子:
prop('length')('hello'); //> 5 | Ramda's curried implementation
prop('length', 'hello'); //> 5 | Underscore and others
I ended up with this implementation (similar to underscore's) that does work:我最终得到了这个确实有效的实现(类似于下划线):
export function prop<O, K extends keyof O>(key: K, obj: O): O[K] {
return obj[key];
}
But when I change it to a curried version:但是当我将其更改为咖喱版本时:
export function prop<O, K extends keyof O>(key: K) {
return function prop__(obj: O): O[K] {
return obj[key];
}
}
I get an error when I try to invoke it as prop('someProp')(someObj)
;当我尝试将其作为prop('someProp')(someObj)
调用时出现错误; as I hover over prop
I get an error that says Argument of type 'someProp' is not assignable to parameter of type 'never'
and I really don't know why.当我将鼠标悬停在prop
我收到一条错误消息,指出Argument of type 'someProp' is not assignable to parameter of type 'never'
我真的不知道为什么。
How can I go about this?我该怎么办?
UPDATE : Solved!更新:解决了! And now these tests pass:现在这些测试通过了:
describe('prop', () => {
test('should obtain prop value from JSON object', () => {
const author = { name: 'Luis', age: 25 };
const getAge = prop('age');
expect(getAge(author)).toBe(25);
});
test('should obtain prop value from known data type', () => {
expect(prop('length')('lovecraft')).toBe(9);
});
});
Oh man, I didn't know Record and PropertyKey existed...哦,伙计,我不知道 Record 和 PropertyKey 存在...
You need to move object's generic parameter to the second function (where object is provided as a function's parameter):您需要将对象的通用参数移动到第二个函数(其中对象作为函数的参数提供):
export function prop<K extends PropertyKey>(key: K) {
return <O extends Record<K, any>>(obj: O): O[K] => obj[key];
}
const someObj = { someProp: 'a' };
const someProp = prop('someProp')(someObj) // someProp is string
// Expect error
const someProp1 = prop('someProp1')(someObj) // Property 'someProp1' is missing in type '{ someProp: string; }
O extends Record<K, any>
constraint prevents passing objects that don't have K
property O extends Record<K, any>
约束阻止传递没有K
属性的对象
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.