0
# Literal Types
1
2
Validates exact literal values using SameValueZero equality. Literal types are essential for creating strict value constraints and union types with specific allowed values.
3
4
## Capabilities
5
6
### Literal
7
8
Creates a validator that accepts only the exact specified value.
9
10
```typescript { .api }
11
/**
12
* Validates that a value is exactly equal to the specified literal value
13
* Uses SameValueZero equality (same as Map/Set)
14
* @param value - The exact value to validate against
15
* @example Literal("hello").check("hello") // "hello"
16
* @example Literal(42).check(42) // 42
17
* @example Literal(true).check(false) // throws ValidationError
18
*/
19
function Literal<T extends LiteralValue>(value: T): Runtype<T>;
20
21
type LiteralValue = undefined | null | boolean | number | bigint | string;
22
```
23
24
**Usage Examples:**
25
26
```typescript
27
import { Literal, Union } from "runtypes";
28
29
// String literals
30
const StatusActive = Literal("active");
31
const StatusInactive = Literal("inactive");
32
33
// Number literals
34
const Zero = Literal(0);
35
const FortyTwo = Literal(42);
36
37
// Boolean literals
38
const True = Literal(true);
39
const False = Literal(false);
40
41
// Special value literals
42
const Null = Literal(null);
43
const Undefined = Literal(undefined);
44
45
// BigInt literals
46
const BigZero = Literal(0n);
47
const LargeBigInt = Literal(123456789012345678901234567890n);
48
```
49
50
### Enum-like Patterns
51
52
Create enum-like validation using unions of literals.
53
54
```typescript
55
import { Literal, Union } from "runtypes";
56
57
// Status enum
58
const Status = Union(
59
Literal("draft"),
60
Literal("published"),
61
Literal("archived")
62
);
63
64
type StatusType = Static<typeof Status>; // "draft" | "published" | "archived"
65
66
// HTTP Methods
67
const HttpMethod = Union(
68
Literal("GET"),
69
Literal("POST"),
70
Literal("PUT"),
71
Literal("DELETE"),
72
Literal("PATCH")
73
);
74
75
// Numeric enum
76
const Priority = Union(
77
Literal(1),
78
Literal(2),
79
Literal(3)
80
);
81
82
// Usage
83
const userStatus = Status.check("published"); // "published"
84
const method = HttpMethod.check("GET"); // "GET"
85
const priority = Priority.check(2); // 2
86
```
87
88
### Configuration Objects
89
90
Use literals for configuration with specific allowed values.
91
92
```typescript
93
import { Literal, Union, Object } from "runtypes";
94
95
const DatabaseConfig = Object({
96
host: String,
97
port: Number,
98
ssl: Union(Literal(true), Literal(false)), // explicit boolean literals
99
logLevel: Union(
100
Literal("error"),
101
Literal("warn"),
102
Literal("info"),
103
Literal("debug")
104
),
105
connectionPool: Union(
106
Literal("single"),
107
Literal("pooled"),
108
Literal("cluster")
109
)
110
});
111
112
// Usage
113
const config = DatabaseConfig.check({
114
host: "localhost",
115
port: 5432,
116
ssl: true,
117
logLevel: "info",
118
connectionPool: "pooled"
119
});
120
```
121
122
### Discriminated Unions
123
124
Create discriminated unions using literal types for type discrimination.
125
126
```typescript
127
import { Literal, Union, Object } from "runtypes";
128
129
const SuccessResponse = Object({
130
type: Literal("success"),
131
data: Unknown,
132
timestamp: Number
133
});
134
135
const ErrorResponse = Object({
136
type: Literal("error"),
137
message: String,
138
code: Number
139
});
140
141
const LoadingResponse = Object({
142
type: Literal("loading"),
143
progress: Number.optional()
144
});
145
146
const ApiResponse = Union(SuccessResponse, ErrorResponse, LoadingResponse);
147
148
type ApiResponseType = Static<typeof ApiResponse>;
149
// {
150
// type: "success";
151
// data: unknown;
152
// timestamp: number;
153
// } | {
154
// type: "error";
155
// message: string;
156
// code: number;
157
// } | {
158
// type: "loading";
159
// progress?: number;
160
// }
161
162
// Usage with type narrowing
163
function handleResponse(response: unknown) {
164
const validResponse = ApiResponse.check(response);
165
166
switch (validResponse.type) {
167
case "success":
168
// TypeScript knows this is SuccessResponse
169
console.log("Data:", validResponse.data);
170
break;
171
case "error":
172
// TypeScript knows this is ErrorResponse
173
console.error(`Error ${validResponse.code}: ${validResponse.message}`);
174
break;
175
case "loading":
176
// TypeScript knows this is LoadingResponse
177
console.log("Loading...", validResponse.progress);
178
break;
179
}
180
}
181
```
182
183
### Literal Edge Cases
184
185
```typescript
186
import { Literal } from "runtypes";
187
188
// NaN handling (uses SameValueZero equality)
189
const NaNLiteral = Literal(NaN);
190
NaNLiteral.check(NaN); // passes - NaN === NaN with SameValueZero
191
192
// Zero handling
193
const PositiveZero = Literal(0);
194
const NegativeZero = Literal(-0);
195
PositiveZero.check(-0); // passes - 0 === -0 with SameValueZero
196
197
// String vs Number distinction
198
const StringFive = Literal("5");
199
const NumberFive = Literal(5);
200
StringFive.check(5); // throws - "5" !== 5
201
NumberFive.check("5"); // throws - 5 !== "5"
202
```
203
204
### Combining with Other Types
205
206
```typescript
207
import { Literal, Union, Object, Array } from "runtypes";
208
209
// Optional literal values
210
const Theme = Union(Literal("light"), Literal("dark")).optional();
211
212
// Arrays of literals
213
const Permissions = Array(Union(
214
Literal("read"),
215
Literal("write"),
216
Literal("admin")
217
));
218
219
// Objects with literal constraints
220
const User = Object({
221
name: String,
222
role: Union(Literal("user"), Literal("admin"), Literal("moderator")),
223
preferences: Object({
224
theme: Union(Literal("light"), Literal("dark")),
225
language: Union(Literal("en"), Literal("es"), Literal("fr")),
226
notifications: Literal(true).or(Literal(false))
227
})
228
});
229
230
type UserType = Static<typeof User>;
231
// {
232
// name: string;
233
// role: "user" | "admin" | "moderator";
234
// preferences: {
235
// theme: "light" | "dark";
236
// language: "en" | "es" | "fr";
237
// notifications: boolean;
238
// };
239
// }
240
```