簡體   English   中英

打字稿 tapAsync 功能無法設置正確的打字

[英]Typescript tapAsync function unable to set correct typings

我希望能夠使用 typescript 將幾個 ES6 異步函數一起使用。 如果tap 函數沒有返回任何內容,tap 函數應該返回參數,但如果tap 函數返回任何內容,則tap 返回值。

打字稿游樂場示例

我可以讓它在不輸入的情況下工作,但在設置類型時遇到問題。 有關在 Javascript 中工作的代碼示例,請參閱代碼段。

被抽頭的函數被簡單地用xx => 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM