如何正确声明含字符串/数字键的Map?TypeScript报错求助
问题重现
尝试声明类型为Map<string | number, () => void>的Map实例,代码如下:
const a: Map<string | number, () => void> = new Map([ [ 2, () => { console.log('a'); }, ], [ '2', () => { console.log('a'); }, ], ]);
抛出错误:
TS2322: Type 'Map<number | (() => void), number | (() => void)>' is not assignable to type 'Map<string | number, () => void>'.
Type 'number | (() => void)' is not assignable to type 'string | number'.
Type '() => void' is not assignable to type 'string | number'.
Type '() => void' is not assignable to type 'number'.
使用自定义联合类型Map<NumberOrString, () => void>时,仍出现相同错误。
错误原因
TypeScript对数组字面量的类型推断出现偏差,它没有正确识别出数组里每一项是[string | number, () => void]的元组,反而把整个数组的元素类型推断成了(number | (() => void))[],导致Map的键和值类型都被错误推导。
解决方案
方案一:显式标注Map的泛型参数
在new Map后直接指定泛型参数,明确键和值的类型:
const a: Map<string | number, () => void> = new Map< string | number, () => void >([ [2, () => console.log('a')], ['2', () => console.log('a')], ]);
方案二:对传入的数组做类型断言
直接告诉TypeScript,传入Map的数组是[string | number, () => void][]类型:
const a: Map<string | number, () => void> = new Map( [ [2, () => console.log('a')], ['2', () => console.log('a')], ] as [string | number, () => void][] );
方案三:提前定义数组并标注类型
先定义键值对数组并指定类型,再传入Map构造函数:
const entries: [string | number, () => void][] = [ [2, () => console.log('a')], ['2', () => console.log('a')], ]; const a: Map<string | number, () => void> = new Map(entries);
内容的提问来源于stack exchange,提问作者woodsding

