TypeScript中如何通过映射类型将数组转为指定键的字典类型?
TypeScript泛型映射类型转换问题
问题背景
定义了以下TypeScript类型与常量:
export type ParamDecl = ["input" | "output", "float" | "int" | "bool", string][]; const params: ParamDecl = [["input", "float", "x"], ["output", "float", "a"], ["input", "int", "y"], ["output", "bool", "b"]];
想要通过泛型与映射类型将ParamDecl转换为如下字典类型:
export type Converted = { x: "float", a: "float", y: "int", b: "bool" };
尝试编写的映射类型如下,但出现错误:
export type AsDictionary<X extends ParamDecl> = { [K in keyof X as X[K][2]]: X[K][1] };
错误信息
Type 'X[K][2]' is not assignable to type 'string | number | symbol'. Type 'X[keyof X][2]' is not assignable to type 'string | number | symbol'. Type 'X[string][2] | X[number][2] | X[symbol][2]' is not assignable to type 'string | number | symbol'. Type 'X[string][2]' is not assignable to type 'string | number | symbol'.ts(2322) Type '2' cannot be used to index type 'X[K]'.ts(2536)
错误原因
keyof X包含的不只是数组的数字索引,还包括数组原型上的字符串键(比如length、push等)。当K取这些字符串键时,X[K]对应的是数组的属性类型(比如number),不是ParamDecl定义的元组类型,所以无法用索引2访问,触发第二个错误。- 同样,非数字索引对应的
X[K][2]类型无法保证是合法的对象键类型(string | number | symbol),触发第一个错误。
解决方案
需要将K限制为数组的数字索引,只遍历数组的元素元组。修改后的映射类型如下:
export type AsDictionary<X extends ParamDecl> = { [K in Extract<keyof X, number> as X[K][2]]: X[K][1] };
或者用keyof X & number也能达到同样效果:
export type AsDictionary<X extends ParamDecl> = { [K in keyof X & number as X[K][2]]: X[K][1] };
验证
用typeof params测试该类型:
type Test = AsDictionary<typeof params>; // Test的类型为 { x: "float"; a: "float"; y: "int"; b: "bool" },完全符合需求
内容的提问来源于stack exchange,提问作者damix911
相关产品推荐
相关产品推荐

