Union types
A union type is formed from two or more types. A value of that type may be any one of the members.
function printId(id: number | string) {
console.log("Your ID is: " + id);
}
printId(101); // OK
printId("202"); // OK
printId({ myID: 22342 });
// Error: Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.
You can also write leading | for readability:
function printTextOrNumberOrBool(
textOrNumberOrBool: string | number | boolean,
) {
console.log(textOrNumberOrBool);
}
Working with unions (narrowing)
TypeScript only allows operations that are valid for every member of the union. So this fails:
function printId(id: number | string) {
console.log(id.toUpperCase());
// Error: Property 'toUpperCase' does not exist on type 'string | number'.
}
Narrow the type with the same checks you would write in JavaScript:
function printId(id: number | string) {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id);
}
}
Array.isArray works the same way:
function welcomePeople(x: string[] | string) {
if (Array.isArray(x)) {
console.log("Hello, " + x.join(" and "));
} else {
console.log("Welcome lone traveler " + x);
}
}
If every member shares a method, you can call it without narrowing:
function getFirstThree(x: number[] | string) {
return x.slice(0, 3);
}
Both arrays and strings have slice.
Type aliases
A type alias names any type so you can reuse it:
type Point = {
x: number;
y: number;
};
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });
Aliases work for unions and primitives too:
type ID = number | string;
Aliases are only names : they do not create a distinct runtime type:
type UserInputSanitizedString = string;
function sanitizeInput(str: string): UserInputSanitizedString {
return str.trim();
}
let userInput = sanitizeInput(" hello ");
userInput = "new input"; // still allowed : both are just string
Practice
type Status = "idle" | "loading" | "error";
function handle(id: ID, status: Status) {
// narrow id, then log status
}
- Define
IDasnumber | string. - Implement
handleso string ids are uppercased and number ids are printed as-is. - Pass an invalid status like
"done"and fix the call site.