A union type lets a value have any one of several types without giving up type checking. Write `string | number` to accept either type. Unlike `any`, a union limits the values that can be assigned and the operations that can be performed. section 7.3
A result with two possible types
In `src/index.ts`, `function calculateTax(amount: number, format: boolean): string | number` returns a formatted string when `format` is true and a number otherwise. Both calls still have the declared `string | number` result type: the compiler does not infer a narrower result from the boolean argument. A union can contain more than two types. section 7.3
Treat a union as a type in its own right. Before narrowing, use only members available on every constituent type. A `string | number` value has `toString`, but calling `toFixed` or `charAt` directly produces a compiler error because each belongs to only one constituent. section 7.3
Use a runtime check when you need a constituent’s members: `if (typeof value === "number") { console.log(value.toFixed(2)); }`. An `as number` assertion also changes what the compiler permits, but it does not convert or check the runtime value. An assertion to an unrelated type, such as `boolean` for `string | number`, is normally rejected. section 7.4 section 7.4.1
With `strictNullChecks` enabled, include `null` explicitly when it is a possible result: `string | number | null`. Test `value !== null` before using the remaining union. A trailing `!` removes null from the compiler’s view without a runtime check; use it only when null cannot occur, or a runtime error may follow. section 7.7.1 section 7.7.2 section 7.7.3
Objects in one array
For `Product | Person`, both object types define `id` and `name`, so an array item can be read through those properties without narrowing. `price` and `city` are not available on the union. Because the types disagree about `id`, its property type is `number | string`; their shared `name` remains `string`. section 10.2.4 section 10.2.5
Listing 10.12 Using a type union in the index.ts file in the src folder
type Product = {
id: number,
name: string,
price?: number
};
type Person = {
id: string,
name: string,
city: string
};
let hat = { id: 1, name: "Hat", price: 100 };
let gloves = { id: 2, name: "Gloves", price: 75 };
let umbrella = { id: 3, name: "Umbrella", price: 30 };
let bob = { id: "bsmith", name: "Bob", city: "London" };
let dataItems: (Product | Person)[] = [hat, gloves, umbrella, bob];
dataItems.forEach(item =>
console.log(`ID: ${item.id}, Name: ${item.name}`));
The complete `src/index.ts` listing shows the two object shapes, their union-typed array, and access to shared properties. section 10.2.4
A union describes possibilities, not every relationship between them. A function accepting `number | null` and returning `number | null` does not tell callers that a number argument always produces a number. Function type overloads can express that mapping. Likewise, a collection typed for `Person | Product` can contain both; use a generic type parameter when each collection should retain its own item type. section 8.2.4 section 12.2.1
Unions also combine literal values with ordinary types: `string | true | 3` accepts any string, but only those specified boolean and number values. In JavaScript files, a JSDoc parameter annotation such as `{ number | string }` can describe the same choice to the TypeScript compiler. section 9.5.2 section 15.3.1









