![](/img/trans.png)
[英]Class wrapping a function: get correct typings and access to number of arguments (in typescript)
[英]Typescript tapAsync function unable to set correct typings
我希望能夠使用 typescript 將幾個 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))
我不是在被輕敲功能打字稿設置任何類型的,但我一直在使用第二函數的兩個泛型類型的嘗試,但也不能正常工作
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', foo) return { foo, 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 ====================
我一直在玩代碼並進一步充實了類型,但是現在當它返回一個新對象時,即使它是相同的形狀,我也會在這兩個函數上遇到錯誤。
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>
(x:X)=>Promise<void | Y>
作為回報。 這發生了,因為在第一次調用非返回異步function :Promise<void>
Y 被Promise.then(...
為該類型,因此Promise.then(...
將嘗試將 X 作為 void | Args 在下一次調用,導致(x: void | Args)=>....
這與(x: Args)=>...
預期不兼容。
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 不是空的,它永遠不會返回空。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.