我有以下示例函数(compose来自Ramda):
declare function compose<V0, T1, T2>(fn1: (x: T1) => T2, fn0: (x0: V0) => T1): (x0: V0) => T2;
interface User {
id: number
}
function fn1(input: any): User {
return {id: 1};
}
function fn2<I, O>(fn: (i: I) => O): (i: I) => O {
return (data) => {
try {
return fn(data);
} catch (e) {
return undefined
}
};
}
当我试图像这样使用它时:
compose(fn2(user => user.id), fn1);
TypeScript会抛出以下错误:
TS2339:Property 'id' does not exist on type '{}'.
有谁知道,我该怎么做才能帮助TypeScript推断user
的正确类型?
当然,以下代码将起作用:
compose<any, User, number>(fn2(user => user.id), fn1);
答案 0 :(得分:1)
看起来参数类型是从左到右解决的,因为您正在向任何函数编写任何函数,首先会出现该错误。看看这个类似但代码相反的代码:
declare function compose<V0, T1, T2>(fn0: (x0: V0) => T1, fn1: (x: T1) => T2,): (x0: V0) => T2;
interface User {
id: number
}
function fn1(input: number): User {
return {id: 1};
}
function fn2<I, O>(fn: (i: I) => O): (i: I) => O {
return (data) => {
try {
return fn(data);
} catch (e) {
return undefined
}
};
}
compose(fn1, fn2(user => user.id));
它可以像你期望的那样工作。但必须改变作文定义。
与Titian Cernicova的答案类似,您可以至少定义进入您的撰写链的第一个参数元素,如下所示:
declare function compose<T1 = any, T2 = any, V0 = any>(fn1: (x: T1) => T2, fn0: (x0: V0) => T1): (x0: V0) => T2;
interface User {
id: number
}
function fn1(input: number): User {
return {id: 1};
}
function fn2<I, O>(fn: (i: I) => O): (i: I) => O {
return (data) => {
try {
return fn(data);
} catch (e) {
return undefined
}
};
}
compose<User>(fn2(user => user.id), fn1);
答案 1 :(得分:0)
您不必指定所有类型,但需要指定user
参数类型才能生效。
compose(fn2((user: User) => user.id), fn1);
如果您不使用fn2
类型推断可行,但根据fn2返回的所需值,确定fn2
的参数必须是(user:User)=> number
类型对于Typescript编译器来说有点太多了。
这有效:
compose((user) => user.id, fn1);