我在 Typescript 中有一個這樣的函式:
function combine<A, B>(p1: Parser<A>, p2: Parser<B>): Parser<A | B> { … }
是否可以為可變數量的型別變數(A,B,C,...)鍵入它并將結果型別正確設定為Parser<A | B | C | …>?我知道我可以通過為不同的引數手動撰寫型別簽名來做到這一點:
function combine<A>(p1: Parser<A>): Parser<A>;
function combine<A, B>(p1: Parser<A>, p2: Parser<B>): Parser<A | B>;
// …and so on…
function combine(...parsers: Parser<any>[]): Parser<any> { … }
這是唯一的選擇嗎?
附注。我正在看這個類似的問題,但型別有點超出我的頭腦,我不知道它是否是相同的情況(“無限聯合型別”在這里看起來像是一個額外的要求)。
uj5u.com熱心網友回復:
可以使用泛型陣列而不是聯合來實作它。您可以通過以下幾種方式:
創建一個型別并且有能力做很多箭頭函式的實作
type ParserFunc<T extends any[]> = (...args: { [P in keyof T]: T[Parser<P>] }) => Parser<T[number]> const function1: ParserFunc<[string,number]> = (p1, p2) => { ... } // => Parser<string | number> const function2: ParserFunc<[string,string]> = (p1, p2) => { ... } // => Parser<string> const function3: ParserFunc<[string,boolean]> = (p1, p2) => { ... } // => Parser<string | boolean>創建單個標準函式
function combineParser<T extends any[]>(...args: { [P in keyof T]: T[Parser<P>] }): Parser<T[number]> { // ... } combineParser(1,'2',true, null) // => Parser<number | string | boolean | null>
uj5u.com熱心網友回復:
以下是根據引數推斷結果型別的方法。可能這就是你想要達到的目標
function combine<T extends string>(...ps: Parser<T>[]): typeof ps extends Array<infer R> ? R : never {
throw new Error('not implemented')
}
TS游樂場
編輯:
閱讀您的評論后,我意識到您可能想要這樣定義函式:
// generic extending parser Array
function combine<T extends Parser[]>(...ps: T): typeof ps extends Array<infer R> ? R : never {
throw new Error('not implemented')
}
這樣你就可以將元組作為泛型引數傳遞來定義引數的型別和位置
const result = combine3<[B, A]>(parserB, parserA)
// typeof result is B | A
或者不強制位置,只是讓 ts 推斷回傳型別
const result = combine(parserB, parserA, parserA, parserC)
// typeof result is B | A | C
例子
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/311140.html
上一篇:帶記錄的泛型佇列,直接入隊記錄
