Skip to content
Merged
Show file tree
Hide file tree
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
7 changes: 5 additions & 2 deletions docs/architecture/adr/0025-ts-deprecate-enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ In most cases, enums are unnecessary. A readonly (`as const`) object coupled wit
avoids both code generation and type inconsistencies.

```ts
const CipherType = Object.freeze({
export const CipherType = Object.freeze({
Login: 1,
SecureNote: 2,
Card: 3,
Identity: 4,
SshKey: 5,
} as const);

export type CipherType = _CipherType[keyof typeof CipherType];
export type CipherType = (typeof CipherType)[keyof typeof CipherType];
Comment on lines +38 to +46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering about side-by-side exported const and type declarations with the same name, so I gave it a go. It's still surprising to me that in this case import { CipherType } from "@bitwarden/common/vault/enums"; brings in both concerns, but yeah, it works... nicely!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't consider this... ๐Ÿคฏ handy though!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way that the symbols work is not unlike C namespaces. Both namespaces end up being imported. You don't need to specify them, however, because whether the symbol is in type or data position can be inferred.

Copy link
Contributor

@jprusik jprusik Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whether the symbol is in type or data position can be inferred

I wonder if there are any cases where it can't be inferred... (I couldn't think of any)? ๐Ÿค”

Comment on lines +38 to +46
Copy link
Contributor

@jprusik jprusik Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worth mentioning, this specific example is not what main currently looks like, and should be updated in the actual code to match this updated example/guidance (once the blocking typescript version is available).

```

This code creates a `type CipherType` that allows arguments and variables to be typed similarly to
Expand All @@ -62,6 +62,9 @@ let value: CipherType = CipherType.Login;
// โŒ Do not: use type inference
const array = [CipherType.Login]; // infers `number[]`
let value = CipherType.Login; // infers `1`

// โŒ Do not: use type assertions
let value = CipherType.Login as CipherType; // this operation is unsafe
```

:::
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing/code-style/angular.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ property from your component:

```ts
// given:
const EnumLike = { Some = "some", Value: "value" };
const EnumLike = { Some: "some", Value: "value" };
type EnumLike = EnumLike[keyof typeof EnumLike];

// add the input:
Expand Down