元组映射函数类型
tuple mapper function typing
我需要输入一个接受元组并输出它的映射版本的函数
作为第一次尝试,我定义了一个身份元组 returns 一个相同类型的元组
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 类型系统可以声明这样的类型吗?
让我们先稍微改变一下映射器函数:
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 的第一个元素,以及作为另一个元组的其余元素。
如果无法推断出这些,则元组为空,因此我们 return R,结果。
但是,如果是,我们映射剩余的元素,并向结果添加一个包装的第一个元素。
这基本上是一个循环,映射每个元素。
您可以使用映射类型声明类型(当应用于元组类型时会产生一个元组):
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>
我需要输入一个接受元组并输出它的映射版本的函数
作为第一次尝试,我定义了一个身份元组 returns 一个相同类型的元组
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 类型系统可以声明这样的类型吗?
让我们先稍微改变一下映射器函数:
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 的第一个元素,以及作为另一个元组的其余元素。
如果无法推断出这些,则元组为空,因此我们 return R,结果。
但是,如果是,我们映射剩余的元素,并向结果添加一个包装的第一个元素。
这基本上是一个循环,映射每个元素。
您可以使用映射类型声明类型(当应用于元组类型时会产生一个元组):
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>