Skip to content

Conversation

@sxxov
Copy link

@sxxov sxxov commented Mar 30, 2025

resolves #16 & #15, supersedes #17

this PR contains no breaking changes, but adds types & namespaces where possible to shortcut the use of .Value, & .VALUE, as well as compiles a .js file containing all the constants in the project as namespace enums, so consumers can use them in their projects without disabling isolatedModules.

this is achieved using "type duality", basically using the same name for a type & const/namespace. in practice, the following pattern is common:

export type Foo = Helpers.Values<typeof Foo>;
export namespace Foo {
  export const Bar = 1;
  export type Bar = typeof Bar;
  export const Baz = 2;
  export type Baz = typeof Baz;
}

const fooLiteral: Foo = 1;
//                ^ `Foo` type
const fooEnum: Foo = Foo.Baz;
//             ^     ^
//             |     | `Foo.Baz` value, equivalent to `2`
//             | `Foo` type
const fooBarLiteral: Foo.Bar = 1;
//                   ^ `Foo.Bar` type
const fooBarEnum: Foo.Bar = Foo.Bar;
//                ^         ^
//                |         | `Foo.Bar` value, equivalent to `1`
//                | `Foo.Bar` type

however, there are a few caveats when it comes to backwards compatibility:

  • this PR modifies const enums (i.e. .VALUE) to use the same pattern as above. this enables exporting them into the JavaScript world (rather than only via the TypeScript compiler), as well as enables us to reference one single source of truth in the source code when performing compat work (rather than being required to duplicate the literal)
  • this PR deprecates constructs that require code duplication to maintain backwards-compatibility, such as the aforementioned const enums, as well as namespace top-level type declarations of enum values (e.g. TextType.RegularTextType.Caps.Regular). i strongly recommend we keep this deprecation, because this compat code introduces a lot of noise in the codebase.

a few extra notes that were done in this PR are:

  • the dependencies have been bumped to support the modern bundler setting for moduleResolution. it is required to compile in extension-agnostic mode for import paths (e.g. import a from './a';). whilst this setting does come with its own caveats when used in a library, we are bundling our entry points so those don't concern us.

do let me know if this is inline with the goals of the project & if there are any further changes that can be considered to ease merging of this PR. thanks!

@changeset-bot
Copy link

changeset-bot bot commented Mar 30, 2025

⚠️ No Changeset found

Latest commit: 8426801

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@Aidosmf Aidosmf self-requested a review April 5, 2025 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider using value/type duality for namespaces & enums instead of .Value/VALUE

1 participant