Literal Types
Literal types in TypeScript allow us to have exact values for strings, numbers, and booleans. They are not all that useful by themselves.
For example:
let dog: 'greyhound' = 'greyhound';
dog = 'husky';
This will have the following type error: Type '"husky"' is not assignable to type '"dog"'.
Unions
Union Types are a powerful feature of the TypeScript type system that allow us to build new types out of existing ones.
For example, here is a function that works string
and number
:
function addId(id: number | string): number {
if (typeof id === 'string') {
return parseFloat(id);
} else if (typeof id === 'number') {
return id;
}
}
// OK:
addId('100');
// Not OK:
addId([100]);
Literal Unions
When literal types are combined with union types, we can create a condition where we only allow certain values, which is quite useful.
String
For example for string
:
type Direction = 'up' | 'down';
class Controller {
move(direction: Direction) {
if (direction === 'up') {
...
} else if (direction === 'down') {
...
}
}
}
let controller = new Controller();
Controller.move('up');
Controller.move('left');
The second invocation will result in a type error: Argument of type '"left"' is not assignable to parameter type 'Direction'.
Number
Numbers work similarly:
function compare(a: string, b: string): -1 | 0 | 1 {
return a === b ? 0 : a > b ? 1 : -1;
}
Boolean
Of course, booleans only have two values - so effectively the boolean
type is simply the union true | false
:
function contestantAnswer(answer: true | false) {
return answer;
}
is the same as:
function contestantAnswer(answer: boolean) {
return answer;
}
What about Enums?
Enums give us another way to express types that only accept certain literal values.
When an enum member’s value changes, we don’t have to change any other code. With a literal union, we might have to update the value in many places.
From Execute Program:
“We recommend avoiding enums for two reasons. First, enums break TypeScript’s core “type-level extension” rule, complicating our mental model of the language. Second, unions can do the same thing as enums, allowing only a certain set of literal types, with no major drawbacks.”
Conclusion
Here we see how a not particularly useful feature (literals) becomes powerful by combining with another feature (unions) in TypeScript.