我创建了一个TypeScript curried函数,它首先接收一个字符串形式的属性名,然后接收从中获取该属性值的对象。我使用了索引类型来确保每当我试图访问一个不存在的属性时都会得到一个错误:
export interface Dict {
name: string;
age: number;
}
const prop = <T extends Dict, K extends keyof T>(p: K) => (obj: T): T[K] => obj[p];
prop('name')({name: 'John', age: 45}); // John
prop('name2')({name: 'John', age: 45}); // error...
最后一行给出了错误:
error TS2345: Argument of type '"name2"' is not assignable to parameter of type '"name" | "age"'.
这正是我想要的,因为在作为第二个参数给出的对象上不存在属性name2
。
然而,当我尝试使用一个可能的monad来创建一个安全版本时,它给出了一个类似的错误:
const safeProp = <T extends Dict, K extends keyof T>(p: K) => (obj: T): Maybe<{}> => compose2(Maybe.of, prop(p))(obj);
错误出现在compose2
函数的第二个参数上:prop(p)
Argument of type 'K' is not assignable to parameter of type '"name" | "age"'.
我不明白这一点,因为我声明了K extends keyof T
,我认为它是正确的,因为它也适用于prop
函数。
作为参考,compose2
函数:
const compose2 = <A, B, C>(f: (b: B) => C, g: (a: A) => B): ((a: A) => C) => a => f(g(a));
以及Maybe
monad的相关部分:
class Maybe<A> {
static of<A>(x: A): Maybe<A> {
return new Maybe(x);
}
...
}
如何正确键入safeProp
函数?为什么需要将其返回类型指定为Maybe<{}>
而不是Maybe<T[K]>
https://stackoverflow.com/questions/53824319
复制相似问题