Skip to content

Commit 22d9b56

Browse files
committed
refinements from architecture meeting
1 parent b412071 commit 22d9b56

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

docs/contributing/code-style/enums.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,9 @@ use [constant objects][constant-object-pattern] instead of introducing a new enu
77

88
- Use the same name for your type- and value-declaration.
99
- Use `type` to derive type information from the const object.
10+
- Avoid asserting the type of an enum-like. Use explicit types instead.
1011
- Create utilities to convert and identify enums modelled as primitives.
1112

12-
:::tip
13-
14-
This pattern should simplify the usage of your new objects, improve type safety in files that have
15-
adopted TS-strict, and make transitioning an enum to a const object much easier.
16-
17-
:::
18-
1913
### Example
2014

2115
Given the following enum:
@@ -33,14 +27,16 @@ export enum CipherType = {
3327
You can redefine it as an object like so:
3428

3529
```ts
36-
const CipherType = {
30+
// freeze to prevent member injection
31+
export const CipherType = Object.freeze({
3732
Login: 1,
3833
SecureNote: 2,
3934
Card: 3,
4035
Identity: 4,
4136
SshKey: 5,
42-
} as const;
37+
} as const);
4338

39+
// derive the enum-like type from the raw data
4440
export type CipherType = CipherType[keyof typeof CipherType];
4541
```
4642

@@ -55,6 +51,11 @@ function doSomething(type: CipherType) {}
5551

5652
// And used as a value (just like a regular `enum`)
5753
doSomething(CipherType.Card);
54+
55+
// advanced use-case: discriminated union definition
56+
type CipherContent =
57+
| { type: typeof CipherType.Login, username: EncString, ... }
58+
| { type: typeof CipherType.SecureNote, note: EncString, ... }
5859
```
5960
6061
:::warning
@@ -64,17 +65,24 @@ like the following requires you explicitly type your variables:
6465
6566
```ts
6667
// ✅ Do: strongly type enum-likes
67-
const subject = new Subject<CipherType>();
6868
let value: CipherType = CipherType.Login;
69+
const array: CipherType[] = [CipherType.Login];
70+
const subject = new Subject<CipherType>();
6971

7072
// ❌ Do not: use type inference
71-
const array = [CipherType.Login]; // infers `number[]`
7273
let value = CipherType.Login; // infers `1`
74+
const array = [CipherType.Login]; // infers `number[]`
75+
76+
// ❌ Do not: use type assertions
77+
let value = CipherType.Login as CipherType; // this operation is unsafe
7378
```
7479

7580
:::
7681

77-
The following utilities may assist introspection:
82+
## Utilities
83+
84+
The following utilities can be used to maintain type safety after compilation. This code assumes
85+
`const CipherType` is frozen.
7886

7987
```ts
8088
import { CipherType } from "./cipher-type";

0 commit comments

Comments
 (0)