-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Type Guards.ts
91 lines (70 loc) · 2.78 KB
/
Type Guards.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
85
86
87
88
89
90
91
// Type Guarding is the term where you influence the code
// flow analysis via code. TypeScript uses existing JavaScript
// behavior which validates your objects at runtime to influence
// the code flow. This example assumes you've read example:code-flow
// To run through these examples, we'll create some classes,
// here's a system for handling internet or telephone orders.
interface Order {
address: string;
}
interface TelephoneOrder extends Order {
callerNumber: string;
}
interface InternetOrder extends Order {
email: string;
}
// Then a type which could be one of the two Order subtypes or undefined
type PossibleOrders = TelephoneOrder | InternetOrder | undefined;
// And a function which returns a PossibleOrder
declare function getOrder(): PossibleOrders;
const possibleOrder = getOrder();
// We can use the "in" operator to check whether a particular
// key is on the object to narrow the union. ("in" is a JavaScript
// operator for testing object keys.)
if ("email" in possibleOrder) {
const mustBeInternetOrder = possibleOrder;
}
// You can use the JavaScript "instanceof" operator if you
// have a class which conforms to the interface:
class TelephoneOrderClass {
address: string;
callerNumber: string;
}
if (possibleOrder instanceof TelephoneOrderClass) {
const mustBeTelephoneOrder = possibleOrder;
}
// You can use the JavaScript "typeof" operator to
// narrow your union. This only works with primitives
// inside JavaScript (like strings, objects, numbers).
if (typeof possibleOrder === "undefined") {
const definitelyNotAnOder = possibleOrder;
}
// You can see a full list of possible typeof values
// here: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/typeof
// Using JavaScript operators can only get you so far. When
// you want to check your own object types you can use
// type predicate functions.
// A type predicate function is a function where the return
// type offers information to the code flow analysis when
// the function returns true.
// Using the possible order, we can use two type guards
// to declare which type the possibleOrder is:
function isAnInternetOrder(order: PossibleOrders): order is InternetOrder {
return order && "email" in order;
}
function isATelephoneOrder(order: PossibleOrders): order is TelephoneOrder {
return order && "callerNumber" in order;
}
// Now we can use these functions in if statements to narrow
// down the type which possibleOrder is inside the if:
if (isAnInternetOrder(possibleOrder)) {
console.log("Order received via email:", possibleOrder.email);
}
if (isATelephoneOrder(possibleOrder)) {
console.log("Order received via phone:", possibleOrder.callerNumber);
}
// You can read more on code flow analysis here:
//
// - example:code-flow
// - example:type-guards
// - example:discriminate-types