Closed
Description
Like we can narrow down union types with typeof
and instance of
, it would be nice if it could also be narrowed with the javascript in
operator.
Code
type Message1 = { name: "foo"};
type Message2 = { name: "personAdded", personId: string, fullName: string};
type Message3 = { name: "personSelected", personId?: string };
type AnyMessage = Message1 | Message2 | Message3;
function handleMessage(message: AnyMessage) {
// message can be: Message1 | Message2 | Message3
if ("personId" in message) {
// narrowed to: Message2 | Message3
switch (message.name) {
case "personAdded": console.log(`Person added: ${message.fullName}`); break;
case "personSelected": console.log("Person selection changed"); break;
default: exhaustiveFail(message); break; // error: Message1 is not handled
}
}
};
function exhaustiveFail(x: never): never {
throw new Error(`Unexpected object: ${x}`);
}
When using an exhaustive switch/if, it would allow us to reduce the union type down to only the types that can have the specified property.
Remark
What to do with numbers and symbols?
const a = ["foo", 42];
if (0 in a) {...}
if (Symbol.iterator in a) {...}