我需要鍵入一個函式,該函式接受一個元組并輸出它的映射版本
作為第一次嘗試我定義了一個回傳相同型別元組的標識元組
declare const tupleIdentity: <Tup extends readonly any[]>(tup: Tup) => Tup
const [a, b, c, d] = tupleIdentity([1, 's', 3]) // a:number, b:string, c:number, d:undefined
太好了,它跟蹤元組的長度和元素型別!
但找不到回傳元組映射版本的型別,
例如包裝每個元素的物件
// a naive attempt :
type Wrap<T> = { wrapped: T }
declare const tupleMapper: <Tup extends readonly any[]>(tup: Tup)
=> Tup extends Array<infer T> ? Wrap<T>[] : never
const [x, y, z] = tupleMapper([1, 's', 3]) // x,y,z: Wrap<string | number> | undefined
Ts 型別系統可以宣告這樣的型別嗎?
uj5u.com熱心網友回復:
您可以使用映射型別宣告型別(當應用于元組型別時會產生一個元組):
type Wrap<T> = { wrapped: T }
declare const tupleMapper: <Tup extends readonly any[]>(tup: Tup) =>
{[K in keyof Tup]: Wrap<Tup[K]>}
const [x, y, z] = tupleMapper([1, 's', 3]) // [Wrap<number>, Wrap<string>, Wrap<number>]
// x: Wrap<number>
// y: Wrap<string>
// z: Wrap<number>
uj5u.com熱心網友回復:
讓我們先稍微改變一下 mapper 函式:
declare const map: <T extends ReadonlyArray<unknown>>(tuple: T) => MapTuple<T>;
它接受任何元組,然后將該元組傳遞給MapTuple真正發生魔法的型別。
這里是:
type MapTuple<T, R extends ReadonlyArray<unknown> = []> =
T extends readonly [infer First, ...infer Rest]
? MapTuple<Rest, [...R, Wrap<First>]> : R;
我們得到 T 的第一個元素,以及作為另一個元組的剩余元素。
如果它不能推斷出這些,那么元組是空的,所以我們回傳結果 R。
但是,如果是這樣,我們將映射剩余的元素,并將包裝的第一個元素添加到結果中。
這基本上是一個回圈,映射到每個元素。
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/444513.html
