Skip to content

Commit 2329d3a

Browse files
committed
added nominal types examples
1 parent 6e18fe3 commit 2329d3a

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Nominal Typing
2+
// Usefull to model domain concepts that are using primitive data type for it's value
3+
4+
// Method 1: using "interface"
5+
interface Name extends String { _brand: 'Name'; }
6+
const createName = (name: string): Name => {
7+
// validation of business rules
8+
return name as any;
9+
};
10+
11+
// Method 2: using "enum"
12+
enum SurnameBrand { }
13+
type Surname = SurnameBrand & string;
14+
// interface Surname extends String { _brand: 'Surname'; }
15+
const createSurname = (surname: string): Surname => {
16+
// validation of business rules
17+
return surname as any;
18+
};
19+
20+
type Person = {
21+
name: Name;
22+
surname: Surname;
23+
};
24+
25+
const person: Person = {
26+
name: createName('Piotr'),
27+
surname: createSurname('Witek'),
28+
};
29+
30+
// Type system will ensure that the domain objects can only contain correct data
31+
// person.name = 'Karol'; // error
32+
// person.name = person.surname; // error
33+
person.name = createName('Karol'); // OK!
34+
// person.surname = 'Mate'; // error
35+
// person.surname = person.name; // error
36+
person.surname = createSurname('Mate'); // OK!
37+
38+
// easy casting to supertype
39+
let str: string;
40+
str = person.name.toString();
41+
str = person.surname;

0 commit comments

Comments
 (0)