簡體   English   中英

如何返回接口中方法的 ReturnType 元組,這是一種可變參數類型

[英]How to return a tuple of ReturnType of a method in the interface which is a type of variable arguments

我想完成寫一個如下所示的方法。 接口A是生成器的配置類型,我將擁有不同類型的生成器的不同配置,並在函數f中立即使用它們,以便在元組中獲取所有生成的值。

interface A<Output> {
   f: () => Output;
};

const a: A<string> = {
   f: () => 'Hello',
};

const b: A<number> = {
   f: () => 42,
};

function f(...x: ???): ??? {
   return x.map(x => x.f());
}

const y: [string, number] = f(a, b);
console.log(y) // ['Hello', 42]

我怎樣才能做到這一點而沒有任何錯誤?

您可以將該函數表示為作用於泛型映射元組的類型。 如果輸出是T類型的元組,則輸入的類型為{[I in keyof T]: A<T[I]>} ,意思是:對於T元組中的每個索引I ,輸入應該是類型A<T[I]>並且輸出的類型為T[I]

function f<T extends any[]>(...x: { [I in keyof T]: A<T[I]> }) {
    return x.map(x => x.f()) as T;
}

請注意,編譯器不會也可能永遠無法驗證x.map(...)實際生成了預期類型的​​值; 即使一般地表示這樣的轉換也需要類似於 TypeScript 當前不支持的更高級的類型(有關相關功能請求,請參閱microsoft/TypeScript#1213 )。 最簡單的事情就是我上面所做的:通過將x.map(...) as Tx.map(...) as T斷言輸出將是T類型。


讓我們確保它有效:

const y = f(a, b); // [string, number]
console.log(y[0].toUpperCase()) // "HELLO"
console.log(y[1].toFixed(2)) // "42.00"

是的,看起來不錯。


哦,您可以使用ReturnType<T>實用程序類型將此轉換表示為某種東西,但編寫起來更麻煩:

function f<T extends A<any>[]>(...x: T) {
    return x.map(x => x.f()) as { 
      [I in keyof T]: ReturnType<Extract<T[I], A<any>>["f"]> 
    };
}

不過,從調用者的角度來看,它的行為類似。


Playground 鏈接到代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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