有沒有更好的方法來處理 TypeScript 中型別引數的映射?
export function $S(): Parser<[]>
export function $S<A>(fn: Parser<A>): Parser<[A]>
export function $S<A, B>(a: Parser<A>, b: Parser<B>): Parser<[A, B]>
export function $S<A, B, C>(a: Parser<A>, b: Parser<B>, c: Parser<C>): Parser<[A, B, C]>
export function $S<A, B, C, D>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>): Parser<[A, B, C, D]>
export function $S<A, B, C, D, E>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>): Parser<[A, B, C, D, E]>
export function $S<A, B, C, D, E, F>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>): Parser<[A, B, C, D, E, F]>
export function $S<A, B, C, D, E, F, G>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>): Parser<[A, B, C, D, E, F, G]>
export function $S<A, B, C, D, E, F, G, H>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>, h: Parser<H>): Parser<[A, B, C, D, E, F, G, H]>
export function $S<A, B, C, D, E, F, G, H, I>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>, h: Parser<H>, i: Parser<I>): Parser<[A, B, C, D, E, F, G, H, I]>
export function $S<A, B, C, D, E, F, G, H, I, J>(a: Parser<A>, b: Parser<B>, c: Parser<C>, d: Parser<D>, e: Parser<E>, f: Parser<F>, g: Parser<G>, h: Parser<H>, i: Parser<I>, j: Parser<J>): Parser<[A, B, C, D, E, F, G, H, I, J]>
export function $S(...terms: Parser<any>[]): Parser<any[]>
// Minimal definition of parser
interface ParseState {
input: string
pos: number
}
interface ParseResult<T> {
nextPos: number,
value: T,
}
interface Parser<T> {
(state: ParseState): ParseResult<T> | undefined
}
基本上我有一個“序列”函式,它接受任意數量的引數,我想知道是否有一種方法可以自動將每個型別引數映射到回應簽名中,而不是需要為每個數量的引數進行多載。我以前見過這種模式,但現在是 2022 年,所以我希望有更好的方法。
可能與問題相關的背景資訊:每個 Parser 都是一個函式,它采用當前狀態(輸入字串、當前位置)并在該位置匹配時回傳 ParseResult,如果不匹配則回傳 undefined。ParseResult 有一個值和將輸入狀態推進到的新位置。
uj5u.com熱心網友回復:
您可以像這樣使用元組/陣列映射:
declare function $S<T extends any[]>(
...terms: { [I in keyof T]: Parser<T[I]> }
): Parser<T>;
當您將型別映射到陣列/元組型別T(只要T是泛型的)上{[I in keyof T]: F<I>}時,它將導致另一個陣列/元組型別,其中I實際上只會迭代類似數字的索引鍵(盡管在microsoft/ TypeScript#27995這使得這對實作者來說有點困難,但這不是問題,因為在您的示例中Parser<XXX>允許使用任何型別)。XXX
因此,這T是一個與您的示例中的各種型別引數相對應的單個陣列/元組型別的型別(例如,T將[A, B, C]用于您的三引數呼叫簽名)。并且 { [I in keyof T]: Parser<T[I]> }是另一種元組型別,其長度與T每個元素型別被包裝的位置相同Parser<>。所以如果T是[string, number, boolean],那么映射型別是[Parser<string>, Parser<number>, Parser<boolean>]。
讓我們確保這有效:
declare const x: Parser<string>;
declare const y: Parser<number>;
declare const z: Parser<boolean>;
const xyz = $S(x, y, z);
// const xyz: Parser<[string, number, boolean]>
看起來不錯!
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/444501.html
