Skip to content

Commit 24a5d4f

Browse files
author
Maxime Mangel
committed
Fix #173: Complete TypeScript documentation about using interface for tagged union
1 parent 68a348b commit 24a5d4f

File tree

1 file changed

+52
-16
lines changed

1 file changed

+52
-16
lines changed

docs/docs/typescript/features.md

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ function execute(command : Command_$union) {
200200
Added in v4.1.3
201201
</p>
202202

203+
### Discriminated Unions
203204

204205
Even if F# unions can be used in a typed-safe manner from TypeScript, when you build a public API you may want your unions to feel more "native".
205206

@@ -240,24 +241,59 @@ function execute(command: Command) {
240241
}
241242
```
242243

244+
### Interfaces
243245

244-
<!-- Example with interfaces -->
246+
It is also possible to use interfaces instead for describing tagged unions.
245247

246-
type Circle =
247-
abstract kind: string
248-
abstract radius: float
248+
This allows to use interfaces in the F# code to access the fields instead of tuple destructuring.
249249

250-
type Square =
251-
abstract kind: string
252-
abstract sideLength: float
250+
```fs
251+
type Take =
252+
abstract fromIndex: int
253+
abstract toIndex: int
254+
255+
type Edit =
256+
abstract text: string
257+
258+
[<TypeScriptTaggedUnion("type")>]
259+
type Command =
260+
| Take of Take
261+
| Edit of Edit
262+
| Save
263+
```
264+
265+
In TypeScript it becomes:
266+
267+
```ts
268+
export interface Take {
269+
fromIndex: int32,
270+
toIndex: int32
271+
}
272+
273+
export interface Edit {
274+
text: string
275+
}
276+
277+
export type Command =
278+
| Take & { type: "take" }
279+
| Edit & { type: "edit" }
280+
| { type: "save" }
281+
```
253282
254-
[<TypeScriptTaggedUnion("kind")>]
255-
type Shape =
256-
| Circle of Circle
257-
| Square of Square
283+
TypeScript consumer code can now use the union in a natural way:
258284
259-
// usage
260-
let describeShape (shape: Shape) =
261-
match shape with
262-
| Circle c -> $"circle of radius {c.radius}"
263-
| Square s -> $"square of length {s.sideLength}"
285+
```ts
286+
function execute(command: Command) {
287+
switch (command.type) {
288+
case "take":
289+
// command.fromIndex and command.toIndex are available
290+
break;
291+
case "edit":
292+
// command.text is available
293+
break;
294+
case "save":
295+
// No additional data
296+
break;
297+
}
298+
}
299+
```

0 commit comments

Comments
 (0)