Could anyone explain the following behavior in TypeScript (2.4.1)?
Scenario: I have a button which could be "red" or "red and round" (modifications). I would like to have the following syntax to describe it:
button.mods = "red";
button.mods = ["red", "round"];
button.mods = { red: true, round: false };
To describe all of this, I use the following interfaces:
interface HasMods<T extends string>{
mods: T | T[] | { [key in T]?: boolean }
}
interface Button extends HasMods<"round" | "red"> {
}
Ok, now we can do some testing:
let b: Button;
b.mods = "red"; //ok, correct
b.mods = "green"; //error, correct
b.mods = ["red"]; //ok, correct
b.mods = ["green"]; //error, correct
b.mods = {red: true}; //ok, correct
b.mods = {red: true, green: true}; //error, correct
So far everything is perfect. But now a mystery:
b.mods = {red: true, map: false}; //ok, why ???
Why is the value "map" valid for my object of type { [key in T]?: boolean } where T is "red" | "round"? "map" is neither "red" or "round".
Actually, all array methods are valid here - "every", "copyWithin", etc...