-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
Copy pathnominalTyping.ts
84 lines (67 loc) · 1.5 KB
/
nominalTyping.ts
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
namespace Literal {
/** Generic Id type */
type Id<T extends string> = {
type: T,
value: string,
}
/** Specific Id types */
type FooId = Id<'foo'>;
type BarId = Id<'bar'>;
/** Optional: contructors functions */
const createFoo = (value: string): FooId => ({ type: 'foo', value });
const createBar = (value: string): BarId => ({ type: 'bar', value });
let foo = createFoo('sample')
let bar = createBar('sample');
foo = bar; // Error
foo = foo; // Okay
}
namespace EnumDriven {
// FOO
enum FooIdBrand { }
type FooId = FooIdBrand & string;
// BAR
enum BarIdBrand { }
type BarId = BarIdBrand & string;
/**
* Usage Demo
*/
var fooId: FooId;
var barId: BarId;
// Safety!
fooId = barId; // error
barId = fooId; // error
// Newing up
fooId = 'foo' as FooId;
barId = 'bar' as BarId;
// Both types are compatible with the base
var str: string;
str = fooId;
str = barId;
}
namespace Interface {
// FOO
interface FooId extends String {
_fooIdBrand: string; // To prevent type errors
}
// BAR
interface BarId extends String {
_barIdBrand: string; // To prevent type errors
}
/**
* Usage Demo
*/
var fooId: FooId;
var barId: BarId;
// Safety!
fooId = barId; // error
barId = fooId; // error
fooId = <FooId>barId; // error
barId = <BarId>fooId; // error
// Newing up
fooId = 'foo' as any;
barId = 'bar' as any;
// If you need the base string
var str: string;
str = fooId as any;
str = barId as any;
}