Last updated: Feb 27, 2024
Reading time·3 min
Use a string literal type to only allow specific string values in a TypeScript
type, e.g. const str: 'draft' | 'sent' = 'draft';
.
String literals allow us to refer to specific strings in type positions. If the specified string is not in the literal type, an error is thrown.
// ✅ with an interface interface Person { name: 'Alice' | 'Bob' | 'Carl'; } const p: Person = { name: 'Alice', }; // ✅ with a Type Alias type Sizes = 'small' | 'medium' | 'large'; const s: Sizes = 'small';
Here are two more examples.
// ✅ inline const str: 'draft' | 'sent' = 'draft'; // ✅ for function parameters function logMessage(message: 'hello world' | 'howdy world') { console.log(message); } logMessage('hello world');
The examples show how to use a string literal type to only allow assignment to specific string values.
interface Person { name: 'Alice' | 'Bobby Hadz' | 'Carl'; } const p: Person = { name: 'Bobby Hadz', }; console.log(p.name); // 👉️ Bobby Hadz
String literal types allow us to refer to specific strings in type positions.
Assignment of a string that is not a member of the literal type causes an error.
// ⛔️ Type '"bobbyhadz.com"' is not assignable // to type '"draft" | "sent"'. const str: 'draft' | 'sent' = 'bobbyhadz.com';
An easy way to think about string literal types is that they are a union type with specific string values instead of types.
You can also use a string literal type when typing a function's parameter.
function logMessage(message: 'hello world' | 'howdy world') { console.log(message); } // ✅ Works logMessage('hello world'); // ⛔️ Error logMessage('bobbyhadz.com');
The function can be called with one of two strings and trying to call it with any other value causes an error.
boolean
is just an alias for the union true | false
.Alternatively, you could use an enum.
Enums allow us to define a set of named constants. If the specified string is not a member of the enum, an error is thrown.
enum EmailStatus { Read = 'READ', Unread = 'UNREAD', Draft = 'DRAFT', } // ✅ using interfaces interface JobEmails { status: EmailStatus; } const obj: JobEmails = { status: EmailStatus.Read, }; // ✅ inline assignment const emailStatus: EmailStatus = EmailStatus.Read;
Enums are sometimes easier to read than string literal types.
The emailStatus
variable can only have one of the 3 values that are present in
the EmailStatus
enum.
An assignment of a different string would cause the type checker to throw an error.
enum EmailStatus { Read = 'READ', Unread = 'UNREAD', Draft = 'DRAFT', } // ⛔️ Error: Type '"bobbyhadz.com"' is not // assignable to type 'EmailStatus'.ts(2322) const emailStatus: EmailStatus = 'bobbyhadz.com';
The main advantage of using enums over string literal types is that they make your code easier to read and organize.
The whole purpose of enums is to define a group of named and related constants.
I've also written an article on how to check if a string is in a union.
You can learn more about the related topics by checking out the following tutorials: