Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: [M3-7012] - Add documentation for Typescript unions, const enums and objects #9535

Merged
merged 2 commits into from
Aug 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions docs/development-guide/13-coding-standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,68 @@ The styles for Cloud Manager are located in three places:
- The breakpoints can be modified at `/foundations/breakpoints/index.ts`.
- Component-specific styles may be defined either at the end of the component file or in a dedicated file, named `ComponentName.styles.tsx`. Refer to the guidelines outlined in the "Styles" section of [Component Structure](02-component-structure.md#styles).

## Typesript Unions, Const Enums and Objects
In our development process, we often encounter scenarios where we need to handle various messages or descriptions in our application. These messages can range from short, pithy statements to longer, more descriptive texts. To ensure a consistent and maintainable approach, we can use union types for lists of pithy data and const enums or plain old JavaScript objects (POJOs) for longer descriptions.

### Union Types for Pithy Data
When dealing with short and concise messages, like error notifications or status updates, using union types can provide a clean and easily understandable way to define the different message types. Union types allow us to define a value that can be one of several types. In this case, we can define a union type for pithy messages using string literals:

```
type CreateTypes = 'fromApp' | 'fromStackScript' | 'fromImage'
```

### Const Enums and POJOs for Longer Descriptions
For longer descriptions that require more context and detail, const enums or plain old JavaScript objects (POJOs) are more suitable. Both approaches provide a structured way to define and organize multiple messages while allowing for descriptive properties.

#### Const Enums Approach:
```
const enum NoOptionsMessage {
Error = 'An error occurred while fetching your options',
NoOptions = 'You have no options to choose from',
NoResults = 'No results',
}
```
With const enums, we define a set of related constants with descriptive names and associated values. Const enums offer benefits primarily during compile-time rather than runtime. Unlike regular enums, const enums do not generate any JavaScript code during compilation. Instead, their values are inlined directly into the generated JavaScript code at compile-time.

#### POJOs Approach:
```
const NoOptionsMessage = {
Error: 'An error occurred while fetching your options',
NoOptions: 'You have no options to choose from',
NoResults: 'No results',
} as const;
```
With POJOs, we create a read-only object using the `as const` assertion to ensure that the values cannot be modified after creation.

### Using Generics and typeof to Extract Values from as const Objects
In addition to utilizing const enums and POJOs for longer descriptions, we can further enhance our code's flexibility and type safety by extracting values from objects declared with `as const`. This can be achieved using generics and the `typeof` operator.
```
const CreateTypes = {
App: 'fromApp',
Stackscript: 'fromStackScript',
Image: 'fromImage',
Backup: 'fromBackup',
Linode: 'fromLinode',
} as const;
```
We can define a generic type, `ObjectValues`, that accepts an object type and extracts its values using the `keyof` operator. This provides us with the flexibility to create union types from object values.
```
type ObjectValues<T> = T[keyof T];

// Union type: 'fromApp' | 'fromStackScript' | 'fromImage' | 'fromBackup' | 'fromLinode'
type LinodeCreateFrom = ObjectValues<typeof CreateTypes>;
```
In our specific case, we can use `ObjectValues<typeof CreateTypes>` to extract the values from the `CreateTypes` object.
By utilizing this approach, we ensure that the values passed to `myFunction` are limited to the possible values defined in the `CreateTypes` object. This enhances type safety and prevents accidental usage of incorrect values.
```
function myFunction(type: LinodeCreateFrom) {
// Function implementation
}

myFunction(CreateTypes.Backup); // Works
myFunction('fromBackup'); // Works
```

## Adobe Analytics

### Writing a Custom Event
Expand Down