1+ /*
2+ String literal types allow you to specify the exact value a string can have.
3+ */
4+
5+ let myFavoritePet : "dog" ;
6+ // console.log(myFavoritePet); // undefined
7+
8+ /*
9+ myFavoritePet = "rock";
10+ console.log(myFavoritePet);
11+ // Error: Type '"rock"' is not assignable to type '"dog"'.
12+ */
13+
14+ myFavoritePet = "dog" ;
15+ //console.log(myFavoritePet); // dog
16+
17+ // Together with Type Aliases and Union Types you get a enum-like behavior.
18+ type Species = "cat" | "dog" | "bird" ;
19+
20+ // They works well for User-Defined Type Guards.
21+ interface Pet {
22+ species : Species ;
23+ name : String ;
24+ eat ( ) ;
25+ sleep ( ) ;
26+ }
27+
28+ interface Cat extends Pet {
29+ species : "cat" ;
30+ }
31+
32+ interface Dog extends Pet {
33+ species : "dog" ;
34+ walk ( ) ;
35+ }
36+
37+ interface Bird extends Pet {
38+ species : "bird" ;
39+ sing ( ) ;
40+ }
41+
42+ /*
43+ Error: Interface 'Rock' incorrectly extends interface 'Pet'. Types of property 'species' are
44+ incompatible. Type '"rock"' is not assignable to type '"cat" | "dog" | "bird"'. Type '"rock"' is not
45+ assignable to type '"bird"'.
46+ interface Rock extends Pet {
47+ type: "rock";
48+ }
49+ */
50+
51+ // String Literal Types can be used to distinguish overloads.
52+
53+ function buyPet ( pet :Species , name : String ) : Pet ;
54+ function buyPet ( pet :"cat" , name : String ) : Cat ;
55+ function buyPet ( pet :"dog" , name : String ) : Dog ;
56+ function buyPet ( pet :"bird" , name : String ) : Bird ;
57+ function buyPet ( pet :Species , name : String ) : Pet {
58+ if ( pet === "cat" ) {
59+ return {
60+ species : "cat" ,
61+ name : name ,
62+ eat : function ( ) {
63+ console . log ( `${ this . name } eats.` ) ;
64+ } ,
65+ walk : function ( ) {
66+ console . log ( `${ this . name } walks.` ) ;
67+ } ,
68+ sleep : function ( ) {
69+ console . log ( `${ this . name } sleeps.` ) ;
70+ }
71+ } as Cat ;
72+ } else if ( pet === "dog" ) {
73+ return {
74+ species : "dog" ,
75+ name : name ,
76+ eat : function ( ) {
77+ console . log ( `${ this . name } eats.` ) ;
78+ } ,
79+ walk : function ( ) {
80+ console . log ( `${ this . name } walks.` ) ;
81+ } ,
82+ sleep : function ( ) {
83+ console . log ( `${ this . name } sleeps.` ) ;
84+ }
85+ } as Dog ;
86+ } else if ( pet === "bird" ) {
87+ return {
88+ species : "bird" ,
89+ name : name ,
90+ eat : function ( ) {
91+ console . log ( `${ this . name } eats.` ) ;
92+ } ,
93+ walk : function ( ) {
94+ console . log ( `${ this . name } walks.` ) ;
95+ } ,
96+ sleep : function ( ) {
97+ console . log ( `${ this . name } sleeps.` ) ;
98+ } ,
99+ sing : function ( ) {
100+ console . log ( `${ this . name } sings.` ) ;
101+ }
102+ } as Bird ;
103+ } else {
104+ throw `Sorry we do not have a ${ pet } . Would you like to buy a dog?` ;
105+ }
106+ } ;
107+
108+
109+ function petIsCat ( pet : Pet ) : pet is Cat {
110+ return pet . species === "cat" ;
111+ }
112+
113+ function petIsDog ( pet : Pet ) : pet is Dog {
114+ return pet . species === "dog" ;
115+ }
116+
117+ function petIsBird ( pet : Pet ) : pet is Bird {
118+ return pet . species === "bird" ;
119+ }
120+
121+ function playWithPet ( pet : Pet ) {
122+ console . log ( `Hey ${ pet . name } , lets play.` ) ;
123+ if ( petIsCat ( pet ) ) {
124+ // pet is now from type Cat (pet: Cat)
125+ pet . eat ( ) ;
126+ pet . sleep ( ) ;
127+ /*
128+ // Error: Type '"bird"' is not assignable to type '"cat"'.
129+ // pet.type = "bird";
130+ // Error: Property 'sing' does not exist on type 'Cat'.
131+ // pet.sing();
132+ */
133+ } else if ( petIsDog ( pet ) ) {
134+ // pet is now from type Dog (pet: Dog)
135+ pet . eat ( ) ;
136+ pet . walk ( ) ;
137+ pet . sleep ( ) ;
138+ } else if ( petIsBird ( pet ) ) {
139+ // pet is now from type Bird (pet: Bird)
140+ pet . eat ( ) ;
141+ pet . sing ( ) ;
142+ pet . sleep ( ) ;
143+ } else {
144+ throw "An unknown pet. Did you buy a rock?" ;
145+ }
146+ }
147+
148+ let dog = buyPet ( myFavoritePet /* "dog" as defined above */ , "Dog-Rocky" ) ;
149+ let bird = buyPet ( myFavoritePet /* "bird" as defined above */ , "Bird-Rocky" ) ;
150+ let cat = buyPet ( myFavoritePet /* "cat" as defined above */ , "Cat-Rocky" ) ;
151+
152+ playWithPet ( dog ) ;
153+ console . log ( '-----------------\n' ) ;
154+ playWithPet ( bird ) ;
155+ console . log ( '-----------------\n' ) ;
156+ playWithPet ( cat ) ;
157+ console . log ( '-----------------\n' ) ;
158+
159+ /*
160+ Hey Dog-Rocky, lets play.
161+ Dog-Rocky eats.
162+ Dog-Rocky walks.
163+ Dog-Rocky sleeps.
164+ -----------------
165+
166+ Hey Bird-Rocky, lets play.
167+ Bird-Rocky eats.
168+ Bird-Rocky walks.
169+ Bird-Rocky sleeps.
170+ -----------------
171+
172+ Hey Cat-Rocky, lets play.
173+ Cat-Rocky eats.
174+ Cat-Rocky walks.
175+ Cat-Rocky sleeps.
176+ -----------------
177+ */
0 commit comments