Union types
A union type, written A | B, means a value could be an A or a B — but only one at a time, and you do not know which until you check. Before checking, the compiler only lets you use operations that are valid on every member of the union; checking which one you actually have is called narrowing, and it is the subject of this whole module.
You should see
#7
ABCTS2339: calling a method that not every union member has
function shout(x: string | number): string {
return x.toUpperCase()
}app.ts:2:12 - error TS2339: Property 'toUpperCase' does not exist on type 'string | number'.
Property 'toUpperCase' does not exist on type 'number'.
2 return x.toUpperCase()
~~~~~~~~~~~toUpperCase exists on string but not on number, and x could be either one here. TypeScript refuses to call a method unless it exists on every member of the union — otherwise this would crash at runtime whenever x happened to be a number.
Narrow first with a type guard before calling the string-only method.
function shout(x: string | number): string {
return typeof x === "string" ? x.toUpperCase() : String(x)
}- Union type
- A type meaning "one of these", written with a pipe: string | number.
- Narrowing
- Checking a value at runtime so the compiler can shrink a union down to one specific member inside that branch.
JuniorWhat does string | number mean as a parameter type, and what can you safely do with a value of that type before narrowing it?
It means the value could be a string or could be a number, and you do not know which until you check. Before narrowing, the compiler only allows operations that are valid on both — like comparing with === or passing it to something that accepts either — never a method that exists on only one of the two types.
What they are really testing: Understanding that a union is "could be any of these," not "has every capability of all of these."
