Typescript slå samman enums
Jag försöker slå ihop enum-kartor, koden körs:
enum One {
a = 'a',
}
enum Two {
aa = 'aa',
}
enum Three {
aaa = 'aaa',
}
type unit = One | Two | Three;
const twoFromOne: Map<Two, One> = new Map([[Two.aa, One.a]]);
const threeFromTwo: Map<Three, Two> = new Map([[Three.aaa, Two.aa]]);
const combined: Map<unit, unit> = new Map([
...twoFromOne,
...threeFromTwo,
]);
men jag får ett TypeScript-kompileringsfel:
const twoFromOne: Map<Two, One>
No overload matches this call.
Overload 1 of 3, '(iterable: Iterable<readonly [Two, One]>): Map<Two, One>', gave the following error.
Argument of type '([Two, One] | [Three, Two])[]' is not assignable to parameter of type 'Iterable<readonly [Two, One]>'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
...
Jag förstår inte felet, säger det att en karta tilldelas en annan istället för att slås ihop?
Länk till TS-lekplats
Svar #1
Problemet är följande:
TypeScript härleder på något sätt typen baserat endast på den första mappningen som du tillhandahåller (...twoFromOnw). Du kan lägga till <unit, unit> till MapConstructor (höger sida), så att TypeScript inte härleder den typen, utan använder istället Map<unit, unit>:
const combined: Map<unit, unit> = new Map<unit, unit>([
...threeFromTwo,
...twoFromOne,
]);
Svar #2
Jag tänkte bara att det kanske skulle vara hjälpsamt:
enum Point {
a = 'a',
aa = 'aa',
aaa = 'aaa',
}
const twoFromOne: Map<Point.aa, Point.a> = new Map([[Point.aa, Point.a]]);
const threeFromTwo: Map<Point.aaa, Point.aa> = new Map([[Point.aaa, Point.aa]]);
type Overloading = Map<Point.aa, Point.a> & Map<Point.aaa, Point.aa>
const createMap = <K1 extends Point, V1 extends Point, K2 extends Point, V2 extends Point>(fst: Map<K1, V1>, scd: Map<K2, V2>): Overloading =>
new Map<any,any>([ ...fst, ...scd])
const result = createMap(twoFromOne, threeFromTwo)
result.set(Point.aa, Point.a) // ok
result.set(Point.aaa, Point.aa) // ok
result.set(Point.aaa, Point.a) // expected error
result.set(Point.aa, Point.aa) // expected error
result.get(Point.aa) // Point.a | undefined
result.get(Point.aaa) // Point.aa | undefined
result.get(Point.a) // expected error
