我想创建一个 Map
,其中的键可以是 number
或 string
。我想用构造函数中的值初始化它。有些条目有一个 number
键,有些有一个 string
键。
但是我收到一个 typescript 错误。这是一个 TypeScript 错误,还是我做错了什么?
type MyMap = Map<string | number, string>;
// Errors, incorrectly?
const myMapWithMixedKeys: MyMap = new Map([
['abc', 'String key'],
[123, 'Number key']
]);
// All fine
myMapWithMixedKeys.set('abcd', 'String key');
myMapWithMixedKeys.set(1234, 'Number key');
const myMapStrings: MyMap = new Map([
['abc', 'String key'],
['abcd', 'String key']
]);
const myMapNumbers: MyMap = new Map([
[123, 'Number key'],
[1234, 'Number key']
]);
错误:
No overload matches this call.
Overload 1 of 3, '(iterable: Iterable<readonly [string, string]>): Map<string, string>', gave the following error.
Argument of type '([string, string] | [number, string])[]' is not assignable to parameter of type 'Iterable<readonly [string, string]>'.
Types of property '[Symbol.iterator]' are incompatible.
Type '() => IterableIterator<[string, string] | [number, string]>' is not assignable to type '() => Iterator<readonly [string, string], any, undefined>'.
Type 'IterableIterator<[string, string] | [number, string]>' is not assignable to type 'Iterator<readonly [string, string], any, undefined>'.
Types of property 'next' are incompatible.
Type '(...args: [] | [undefined]) => IteratorResult<[string, string] | [number, string], any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult<readonly [string, string], any>'.
Type 'IteratorResult<[string, string] | [number, string], any>' is not assignable to type 'IteratorResult<readonly [string, string], any>'.
Type 'IteratorYieldResult<[string, string] | [number, string]>' is not assignable to type 'IteratorResult<readonly [string, string], any>'.
Type 'IteratorYieldResult<[string, string] | [number, string]>' is not assignable to type 'IteratorYieldResult<readonly [string, string]>'.
Type '[string, string] | [number, string]' is not assignable to type 'readonly [string, string]'.
Type '[number, string]' is not assignable to type 'readonly [string, string]'.
Types of property '0' are incompatible.
Type 'number' is not assignable to type 'string'.
Overload 2 of 3, '(entries?: readonly (readonly [string, string])[] | null | undefined): Map<string, string>', gave the following error.
Argument of type '([string, string] | [number, string])[]' is not assignable to parameter of type 'readonly (readonly [string, string])[]'.
Type '[string, string] | [number, string]' is not assignable to type 'readonly [string, string]'.
Type '[number, string]' is not assignable to type 'readonly [string, string]'.ts(2769)
最佳答案
问题是 TS 通过其第一个值推断 new Map()
的类型。
即使您只写 let m = new Map([[1, 1], ['2', 2]])
而没有任何输入,也会发生这种情况。
(顺便说一句:当您编写类似 let a = new Array(1, '2')
的代码时,它也会发生在数组中)。
要解决这个问题,您应该强制 TS 理解 Map 的类型是联合类型。我知道有两种方法可以做到这一点:
const myMapWithMixedKeys: MyMap = new Map<string | number, string>([
['abc', 'String key'],
[123, 'Number key']
]);
或者:
const myMapWithMixedKeys: MyMap = new Map([
['abc' as string | number, 'String key'],
[123, 'Number key']
]);
参见 Playground
编辑:IMO,我找到了更好的解决方案。
代替:
type MyMap = Map<string | number, string>;
写:
class MyMap extends Map<string | number, string> { }
现在一切正常。参见 updated Playground
关于typescript - 当键具有多种类型时,如何在构造函数中设置类型化 Map 的初始值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60422719/