Skip to content

feat: allow overriding type of stylex.env in TypeScript#1514

Merged
mellyeliu merged 3 commits intofacebook:mainfrom
pawelblaszczyk5:typed-stylex-env
Mar 11, 2026
Merged

feat: allow overriding type of stylex.env in TypeScript#1514
mellyeliu merged 3 commits intofacebook:mainfrom
pawelblaszczyk5:typed-stylex-env

Conversation

@pawelblaszczyk5
Copy link
Copy Markdown
Contributor

@pawelblaszczyk5 pawelblaszczyk5 commented Mar 6, 2026

What changed / motivation ?

As explained in #1507 this allows user to override type of stylex.env if they're using TypeScript. It uses declaration merging and exposes Register type that can be augmented in the user land. stylex.env is typed by either the default, existing type or whatever user sets as env in the Register type.

Example usage:

declare module '@stylexjs/stylex/lib/types/StyleXTypes' {
  interface Register {
    env: {
      utilities: {
        opacity: (color: string, value: number) => string;
      };
      tokens: {
        colors: {
          primary: string;
        };
      };
    };
  }
}

stylex.env.utilities.opacity('#f00', 0.15);
stylex.env.tokens.colors.primary;
image

You get sweet autocompletion and type checking here and if you adjust types of the env you'll get type errors everywhere where you didn't update the usage. Both constants and utility functions can be typed this way.

Linked PR/Issues

Fixes #1507

Additional Context

Open points:

  • Currently it exports Register from @stylexjs/stylex/lib/types/StyleXTypes which user needs to refer when augmenting module. It could go directly to @stylexjs/stylex but then Flow version would need to export some basically unused type, because the entry point for TS is generated from Flow file if I understand correctly?
  • Flow story? I've did some research and if I understand correctly there's no way to achieve something similar here?
  • In typescript-tests it'll currently impact all files and it doesn't verify whether stylex.env is still the fallback if user didn't override this. This could be fixed by splitting tsconfig.json into multiple projects but I didn't want to pollute it too much and I'm not 100% sure about the value.
  • I've added some basic documentation but I'm not 100% sure whether it's a best place for this. stylex.env currently it's only in the API section and it doesn't feel fully like API, it feels more like guide.
  • As pointed out in the original issue, verifying whether this type matches what user passed to babel config is a bit tricky. These are often separate packages "@stylexjs/stylex" vs "@stylexjs/babel-plugin". Babel config is often untyped. And there're many ways to integrate, e.g. there's also "@stylexjs/unplugin".
  • Currently I'm not verifying whether what user passed here can indeed be what stylex.env allows - object with constants and functions. Not sure how important it is, I've checked out and many TS libraries doesn't verify this.

Open to addressing any of them, I guess some of them could be nice possible improvements for the future.

Pre-flight checklist

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 6, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 6, 2026

@pawelblaszczyk5 is attempting to deploy a commit to the Meta Open Source Team on Vercel.

A member of the Team first needs to authorize it.

) => ':where-any-sibling',
};

export type StyleX$Env = $ReadOnly<{ [string]: mixed }>;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved the type into StyleXTypes.d.ts and StyleXTypes.js to make it possible to make them different across Flow/TS

[babel plugin options](/docs/api/configuration/babel-plugin/#env)._

```tsx
declare module '@stylexjs/stylex/lib/types/StyleXTypes' {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As mentioned in the description - these could be just "@stylexjs/stylex" if we exported this from entry point, that would probably also mean adding some "mock" type in Flow, because entry point is auto generated? Or am I missing something obvious here?

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stylex Ready Ready Preview, Comment Mar 9, 2026 11:49pm

Request Review

Copy link
Copy Markdown
Member

@mellyeliu mellyeliu left a comment

Choose a reason for hiding this comment

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

Also some open questions around what the default shape of stylex.env should be, but this is an improvement to what's currently in main. Thanks!

@mellyeliu mellyeliu merged commit ecd3f36 into facebook:main Mar 11, 2026
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stylex.env type safety

2 participants