You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+49Lines changed: 49 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,54 @@
1
1
# TypeScript Pseudo Dependent Typing Example with Mobx & React
2
2
3
+
# Static Typing Stragegies
4
+
## Discriminated Unions
5
+
### Representing Field States
6
+
A common idiom in View/View Model architectures is to represent an editable field's visibility and read-only state with two independent properties on the View Model. For example, a firstName property that may be invisible in some contexts and read-only in other contexts may be represented with three separate properties on the view model:
7
+
* firstName - a read/write property to which the view two-way data-binds.
8
+
* isFirstNameVisible - a read-only property that may change in time.
9
+
* isFirstNameReadOnly - a read-only property that may change in time.
10
+
11
+
This information representation is fraught with opportunities for improper usage/access such as
12
+
* Reading the firstName property when not isFirstNameVisible.
13
+
* Writing the firstName property when isFirstNameReadOnly.
14
+
15
+
The view model may protect itself from inappropriate access by throwing exceptions but this is terribly opaque and leads to the likelihood of run-time faults.
16
+
17
+
Run-time faults can be avoided altogether by employing Discriminated Unions to represent the valid states in such a way that meaning and usage are explicit and compiler verifiable.
The property is computed because it changes reactively based on the state of the editor.
25
+
26
+
The type signature clearly indicates three possible cases
27
+
* null - indicates that the field is not available. This corresponds to invisible.
28
+
* string - denotes a read-only state of the field. The user can read but not modify.
29
+
* (firstName?: string) => string - represents a getter/setter function which can be used to both read and write the value.
30
+
31
+
By using a discriminated union the TypeScript compiler can guarantee that developers cannot expose a hidden field or allow mutation of a read-only field (without intentionally subverting the type system).
32
+
33
+
### Representing Actions
34
+
Similarly, the common idiom for representing an action in a View Model is to provide a method on the view model for the action and a read-only property that indicates whether the action is available or enabled at the current time.
35
+
36
+
Once again, when modeled this way the type system cannot stop code from attempting to execute the method. Developers only recourse is to check for validity inside the method and throw an exception.
37
+
38
+
This can be modeled in a type-safe fashion with
39
+
```TypeScript
40
+
@computeddoAwesomeThing: null| () =>void;
41
+
```
42
+
43
+
44
+
## Dependent Typing - Cases By Values
45
+
Object oriented code is no stranger to representing Cases with data types (the [State Pattern](https://www.geeksforgeeks.org/state-design-pattern/) concerns itself explicitly with such concerns). A class is a "classificaiton" of thing; a set with members (object instances of the class).
46
+
47
+
An OO class in a nominal type system is
48
+
* A named type where the name has semantic significance i.e. significance is related to the name.
49
+
* A _structure_ of data with accompanying _behaviors_.
0 commit comments