Recently, I purchased an online course that I had put off watching until now. In the course, it specifically mentioned that certain code in TypeScript was not allowed:
type Name = { name: string }
type Age = { age: number }
type UnionBoth = Name | Age
const test = (union: UnionBoth): void => {
if ('name' in union && 'age' in union) {
union.name
union.age
}
}
However, when I tested this code on version 5.4.3
, it surprisingly worked without any errors. Intrigued by this, I decided to run the same code on a previous version and encountered an error message at version 4.8.4:
Property 'name' does not exist on type 'never'.
Property 'age' does not exist on type 'never'.
This led me to question my understanding of unions in TypeScript. Could you provide some clarification on the correct mental model for interpreting the code above?
A closer inspection revealed that in version 5.4.3
, the inferred type of union
within the function is as follows:
(parameter) union: Name & Record<"age", unknown>
Why does there need to be a Record
for just the property age
?
This is my current mental model:
- There are two sets
Name
andAge
. - The union
union
can belong to one of three cases:- It only belongs to
Name
. - It only belongs to
Age
. - It belongs to both, i.e.,
Name & Age
.
- It only belongs to
- Through type-narrowing in the
if
statement, TypeScript should recognize the third case, allowing access to bothname
andage
within the block.