Reputation: 23
I have got some strange behavior of TS while work with enums as object keys. I expect TS error, but it is not, and I don't understand why.
enum List {
sm = "sm",
md = "md",
}
export interface Dictionary<T = any> {
[index: string]: T;
}
export type OptionalDictionary<T, K extends string = string> = { [P in K]?: T };
type MessageType = Dictionary<string | null>;
type MessagesType = OptionalDictionary<MessageType, List>;
type Values = { receiver: List; text: string };
const values = { receiver: List.sm, text: "123" };
const { receiver, text } = values;
const data: MessagesType = {
// [receiver]: { text }, // correct
[receiver]: text // wrong, but no error
};
const data2: MessagesType = {};
// data2[receiver] = { text }; // correct
data2[receiver] = text; // wrong, had error
console.log(data[receiver] === data2[receiver]); // true
Upvotes: 2
Views: 894
Reputation: 328362
This looks like the interaction of a few unfortunate behaviors in TypeScript.
First, computed keys of union types are widened all the way to a string
index, as is the subject of microsoft/TypeScript#13948, a longstanding bug/limitation. So the type of {[receiver]: text}
is seen as {[k: string]: string}
instead of something like {sm: string} | {md: string}
. I'm not sure when or if that will be changed, but that's what's happening.
Second, index signatures (like {[k: string]: string}
are always considered assignable to weak types (types with all optional properties, like {sm?: {text: string}, md?: {text: string}}
), even if the index signature's property type is incompatible with the weak type's property types! This is the subject of microsoft/TypeScript#27144, also considered a bug. Again, no idea when or if this will be addressed; it's listed as "future".
Both of those bugs put together give you the behavior you see: you're allowed to assign {[receiver]: text}
to a variable of type MessagesType
with no error. That's the explanation; not sure what you should do except possibly go to those two GitHub and give them a 👍?
Anyway, hope that helps; good luck!
Upvotes: 4