-
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathassert-never.ts
More file actions
52 lines (45 loc) · 1.16 KB
/
assert-never.ts
File metadata and controls
52 lines (45 loc) · 1.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
Assert that a code path is unreachable.
Use this in the `default` case of a `switch` statement (or the final `else` of an `if`/`else if` chain) to get a compile-time error if a new variant is added to a union type but not handled.
If called at runtime (which should never happen), it throws an `Error` with the unexpected value.
@example
```
import {assertNever} from 'ts-extras';
type Status = 'idle' | 'loading' | 'success' | 'error';
function render(status: Status): string {
switch (status) {
case 'idle': {
return 'Idle';
}
case 'loading': {
return 'Loading...';
}
case 'success': {
return 'Done';
}
case 'error': {
return 'Failed';
}
default: {
return assertNever(status);
}
}
}
```
@category Type guard
*/
export function assertNever(value: never): never {
throw new Error(`Unreachable: \`${describeValue(value)}\``);
}
function describeValue(value: unknown): string {
// Runtime misuse should still produce an Error even for values that cannot be string-coerced directly.
try {
return String(value);
} catch {
try {
return Object.prototype.toString.call(value);
} catch {
return '<Unprintable value>';
}
}
}