LearningTypeScript / site

Companion website for the Learning TypeScript book.
https://learningtypescript.com
MIT License
48 stars 12 forks source link

Article: Why narrowing without a discriminant needs the 'in' operator #82

Open JoshuaKGoldberg opened 2 years ago

JoshuaKGoldberg commented 2 years ago

I actually don't remember the historical reasons for this is the case, but have the rule memorized...

In general, TypeScript won't let you access properties of a value that aren't defined in all possible types the value might be. So you can't do things like:

declare const value: { a: string } | { b: string };

value.a;
//    ~
// Property 'a' does not exist on type '{ a: string; } | { b: string; }'.
//   Property 'a' does not exist on type '{ b: string; }'.

However, you can do an existence check with the in operator. That will work as a form of type narrowing:

declare const value: { a: string } | { b: string };

if ('a' in value) {
  value.a; // Ok
  // ^? { a: string }
}

https://discord.com/channels/508357248330760243/942074070860705852/1008521509532356649