【问题标题】:Typescript function signature that converts an array to tuple of mapped type将数组转换为映射类型的元组的 Typescript 函数签名
【发布时间】:2021-04-20 03:20:10
【问题描述】:

在打字稿中,数组可以通过以下方式转换为元组

type Arr = any[];
const f = < T extends Arr > (...args: [...T]): [...T] => {
  return args;
}

const a = f(1, 'a'); // a is type of [number, string].

我们也可以按类型映射

type TypeMap = {
    'n': number;
    's': string
};

const g = <T extends keyof TypeMap>(args: T): TypeMap[T] => {
    throw null;
}

const b = g('s'); //b is type of string

如何将以上两个要求合二为一?我试过了

const h = <T extends keyof TypeMap>(...args: [...T[]]): [...TypeMap[T][]] => {
    throw null;
}
const c = h('s', 'n');

但是,c 的类型是 (string|number)[] 而不是 [string, number]。 我试过了

const h = <T extends (keyof TypeMap)[]>(...args: [...T]): [...TypeMap[T[number]][]] => {
    throw null;
}

但得到了相同的c。

我找到了使用对象而不是元组的解决方案,但欢迎使用元组解决方案。

const f1 = <T extends keyof TypeMap>(...args: [...T[]]): {[P in T]: TypeMap[P]} => {
    throw null;
}
const {s, n} = f1('s', 'n');

typescript playground

【问题讨论】:

    标签: typescript variadic-tuple-types


    【解决方案1】:

    您想使用mapped tuple。给定T,一个元组类型,{[I in keyof T]: ...T[I]...} 将是另一个元组类型; I 仅迭代 T 的数字索引。请注意,由于 TypeScript 中的错误/限制(请参阅 microsoft/TypeScript#27995),编译器没有意识到 T[I] 将是 T 的元素类型,因此您必须使用像 the Extract utility type 这样的技巧。

    在您的情况下,从输入元组T 扩展Array&lt;keyof TypeMap&gt;,您希望输出元组在数字索引I 处具有TypeMap[T[I]] 类型的元素:

    const h = <T extends (keyof TypeMap)[]>(...args: [...T]): {
        [I in keyof T]: TypeMap[Extract<T[I], keyof TypeMap>]
    } => {
        throw null;
    }
    
    const c = h('s', 'n'); // [string, number] 
    

    Playground link to code

    【讨论】:

    • @qxg 请不要忘记接受答案
    猜你喜欢
    • 2018-02-05
    • 2020-01-19
    • 2019-08-21
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 2023-04-04
    相关资源
    最近更新 更多