如何解决Typescript tapAsync函数无法设置正确的键入
我希望能够使用打字稿同时挖掘一些ES6异步功能。如果tap函数未返回任何内容,tap函数应返回参数,但tap函数未返回任何内容时,tap返回值。
我可以不用输入就可以使用它,但是在设置类型时会遇到问题。请参见代码段,以获取使用Javascript编写代码的示例。
只需使用x
值x => fn(x)
调用窃听函数,然后链接该函数以返回返回值y
或窃听值x
x => fn(x).then(y => y || x)
使用any
类型的第一个版本可以工作,但是在处理被轻击的函数中的类型时,我遇到错误。
const tapAsync = (fn: (x: any) => Promise<any>) => (
x: any
): Promise<any> => fn(x).then((y: any) => y || x)
为了更具体一点,我使用了两个泛型,X
用作初始参数,Y
用作轻击函数的确定值。
const tapAsync = (fn: <X>(x: X) => Promise<X>) => (
x: X
): Promise<Y|X> => fn(x).then(<Y>(y: Y) => y || x)
当我使用tapAsync调用函数时,出现以下错误。
src/index.ts:45:18 - error TS2345: Argument of type '({ foo }: { foo: any; }) => Promise<void>' is not assignable to parameter of type '<X>(x: X) => Promise<X>'.
Types of parameters '__0' and 'x' are incompatible.
Type 'X' is not assignable to type '{ foo: any; }'.
45 .then(tapAsync(one))
~~~
src/index.ts:46:18 - error TS2345: Argument of type '({ foo }: { foo: any; }) => Promise<{ foo: any; bar: string; }>' is not assignable to parameter of type '<X>(x: X) => Promise<X>'.
Types of parameters '__0' and 'x' are incompatible.
Type 'X' is not assignable to type '{ foo: any; }'.
46 .then(tapAsync(two))
~~~
src/index.ts:47:18 - error TS2345: Argument of type '({ foo,bar }: { foo: any; bar: any; }) => Promise<void>' is not assignable to parameter of type '<X>(x: X) => Promise<X>'.
Types of parameters '__0' and 'x' are incompatible.
Type 'X' is not assignable to type '{ foo: any; bar: any; }'.
47 .then(tapAsync(three))
我没有在点击的函数上的打字稿中设置任何类型,但是我尝试在第二个函数 two 上使用泛型,但这也不起作用
async function two<X>({ foo }): Promise<X> {
console.log('two',foo)
return {
foo,bar: 'bar'
}
}
async function one({ foo }) {
console.log('one',foo)
}
async function two({ foo }) {
console.log('two',bar: 'bar'
}
}
async function three({ foo,bar }) {
console.log('three',foo,bar)
}
const tapAsync = fn => x => fn(x).then(y => y || x)
Promise.resolve({ foo: 'foo' })
.then(tapAsync(one))
.then(tapAsync(two))
.then(tapAsync(three))
感谢您的帮助!
=============编辑2020-09-01 ==================
我一直在玩代码,并充实了一些类型,但是现在当 two 函数返回一个新对象时,即使形状相同,也会出现错误
new typescript playground example
const tapAsync = <X,Y>(fn: (x: X) => Promise<Y|void>) =>
(x: X): Promise<X|Y> =>
fn(x).then((y: Y|void) => y || x)
解决方法
我认为过载是可行的。而且类型推断看起来是正确的。基本上,这使ts编译器可以推断出没有(x:X)=>Promise<void | Y>
作为返回。发生这种情况的原因是,在第一次调用非返回异步function :Promise<void>
之后,Y被推断为该类型,因此Promise.then(...
会尝试将X作为空|来填充。下次通话中出现Args,导致(x: void | Args)=>....
与预期的(x: Args)=>...
不兼容。
检查这个游乐场your example with overloads
function tapAsync <X,Y>(fn: (x:X)=>Promise<void>): (x:X)=>Promise<X>;
function tapAsync <X,Y>(fn: (x:X)=>Promise<Y>): (x:X)=>Promise<Y>;
function tapAsync <X,Y>(fn: (x: X) => Promise<Y|void>) {
return (x: X) => fn(x).then(y => y||x )
}
编辑:
重读我的答案,我没有提到,罪魁祸首是(y: void| Y )=> Y||X
无法推断出如果初始X不是一个空值,它将永远不会返回空值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。