问题
With Typescript 3.5.1, I can't seem to get the type of values to compile. For the following:
type foo = 'a' | 'b'
const x: Map<foo, {[key: string]: string}> = new Map([
['a', {'ok': 'so'}],
['b', {'nah': 'right'}]
])
tsc barfs up
const x: Map<foo, {
[key: string]: string;
}>
Type 'Map<"a" | "b", { 'ok': string; 'nah'?: undefined; } | { 'nah': string; 'ok'?: undefined; }>' is not assignable to type 'Map<foo, { [key: string]: string; }>'.
Type '{ 'ok': string; 'nah'?: undefined; } | { 'nah': string; 'ok'?: undefined; }' is not assignable to type '{ [key: string]: string; }'.
Type '{ 'ok': string; 'nah'?: undefined; }' is not assignable to type '{ [key: string]: string; }'.
Property ''nah'' is incompatible with index signature.
Type 'undefined' is not assignable to type 'string'.
Is this a compiler bug, or am I doing something wrong to make the Map's value generic look like a union type?
A link to the typescript playground
回答1:
I'm pretty sure this is not a bug. Typescript narrows the type of your right side down to {ok: string, nah?: undefined} | {ok?: undefined, nah: string}
, since you have two objects that are missing the property of the other. The one that has only "ok" will return undefined if "nah" is accessed and vice-versa.
This means that the initial type {[key: string]: string}
is not valid anymore, because the properties can either return a string ('so' and 'right' are subtypes of string) or undefined.
The simpliest way around this is to allow these undefined values by using Map<foo, {[key: string]: string | undefined}>
.
Edit: Corrected the inferred type - thanks to jcalz for pointing that out!
回答2:
TypeScript's type inference can be a bit confusing sometimes. It is never perfect and the TypeScript team had to make hard choices. You get one of these choices that does not match your expectations...
You can get ride of type inference by explicitly specifying the generic types:
const x = new Map<foo, {[key: string]: string}>([
['a', {'ok': 'so'}],
['b', {'nah': 'right'}]
])
来源:https://stackoverflow.com/questions/57128823/nested-typescript-map-type