Skip to content

[code-infra] Convert @mui/styled-engine to TypeScript#48544

Open
Janpot wants to merge 3 commits into
mui:masterfrom
Janpot:code-infra/styled-engine-typescript
Open

[code-infra] Convert @mui/styled-engine to TypeScript#48544
Janpot wants to merge 3 commits into
mui:masterfrom
Janpot:code-infra/styled-engine-typescript

Conversation

@Janpot
Copy link
Copy Markdown
Member

@Janpot Janpot commented May 19, 2026

Converts @mui/styled-engine to true TypeScript (same setup as @mui/utils): handwritten .js + .d.ts source replaced with .ts/.tsx, declarations now emitted by tsc instead of copied.

  • The public type surface is unchanged:
  • Emitted JS is unchanged except index's default export (export default function styledfunction styled; export default styled, same runtime), an inherent result of typing the default as emotion's CreateStyled. Remaining .d.ts deltas are type-only forms (import type, export type *, declare) that preserve the exported types exactly.
  • @mui/system (the only downstream type consumer) typechecks unchanged; package typecheck and the 19 unit/browser tests pass.

Published-tarball diff (base → PR HEAD): @mui/styled-engine@dd4d4f4 vs @868dc99no significant differences found between the packages.

Recording the methodology in a skill for reuse on other packages: #48545

@Janpot Janpot force-pushed the code-infra/styled-engine-typescript branch 4 times, most recently from 0eb81ef to e2dad6f Compare May 19, 2026 12:01
@Janpot Janpot force-pushed the code-infra/styled-engine-typescript branch from e2dad6f to e84b914 Compare May 19, 2026 13:00
@code-infra-dashboard
Copy link
Copy Markdown

code-infra-dashboard Bot commented May 19, 2026

Deploy preview

https://deploy-preview-48544--material-ui.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/material 0B(0.00%) 0B(0.00%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@Janpot Janpot force-pushed the code-infra/styled-engine-typescript branch 2 times, most recently from 56eb2a4 to c379788 Compare May 19, 2026 15:18
@Janpot Janpot requested a review from Copilot May 20, 2026 09:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Converts @mui/styled-engine from handwritten .js + .d.ts sources to “true TypeScript”, emitting declarations via tsc (with Babel still responsible for JS transpilation), and wires it into project references for downstream typechecking (notably @mui/system).

Changes:

  • Replaces source files in @mui/styled-engine with .ts/.tsx equivalents and adds declaration-only tsconfig.build.json.
  • Updates build/typecheck wiring (package build script, exports, and @mui/system TS project references).
  • Adds/adjusts unit tests to cover dev warning behavior and TS typing changes.

Reviewed changes

Copilot reviewed 14 out of 19 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pnpm-lock.yaml Adds @types/prop-types to the lockfile for the TS migration.
packages/mui-system/tsconfig.build.json Adds a project reference to mui-styled-engine so mui-system can typecheck/build against it.
packages/mui-styled-engine/tsconfig.json Updates TS compiler options for the package’s TS sources.
packages/mui-styled-engine/tsconfig.build.json Adds declaration-only TS build config (composite + emitDeclarationOnly).
packages/mui-styled-engine/src/StyledEngineProvider/StyledEngineProvider.tsx Converts provider implementation to TS with explicit props/types and internal stripping.
packages/mui-styled-engine/src/StyledEngineProvider/StyledEngineProvider.test.tsx Updates tests for the new TS typings.
packages/mui-styled-engine/src/StyledEngineProvider/StyledEngineProvider.d.ts Removes handwritten declaration (now emitted by tsc).
packages/mui-styled-engine/src/StyledEngineProvider/index.ts Switches to type-only re-export to avoid exporting internal runtime helpers.
packages/mui-styled-engine/src/StyledEngineProvider/index.js Removes JS source entrypoint (migrated to TS).
packages/mui-styled-engine/src/styled.test.ts Adds tests for dev warnings on incorrect styled() usage.
packages/mui-styled-engine/src/index.ts Migrates main entry to TS and preserves the public type surface.
packages/mui-styled-engine/src/index.js Removes JS source entrypoint (migrated to TS).
packages/mui-styled-engine/src/GlobalStyles/index.ts Adds type-only re-exports for TS sources.
packages/mui-styled-engine/src/GlobalStyles/index.d.ts Removes handwritten declaration entrypoint (now emitted by tsc).
packages/mui-styled-engine/src/GlobalStyles/GlobalStyles.tsx Migrates GlobalStyles implementation to TS.
packages/mui-styled-engine/src/GlobalStyles/GlobalStyles.test.tsx Adjusts tests for TS typing (annotates theme arg).
packages/mui-styled-engine/src/GlobalStyles/GlobalStyles.js Removes JS source entrypoint (migrated to TS).
packages/mui-styled-engine/src/GlobalStyles/GlobalStyles.d.ts Removes handwritten declaration (now emitted by tsc).
packages/mui-styled-engine/package.json Updates build script, exports to TS sources, and adds @types/prop-types devDependency.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

packages/mui-styled-engine/src/index.ts:6

  • CreateStyled, StyledComponent, and StyledOptions are type-only exports from @emotion/styled, but they’re imported as value specifiers. Since this package’s .ts is transpiled via Babel (not tsc), Babel won’t elide type-only named imports unless they use import type, which can lead to invalid ESM named imports at runtime. Split the import into a value import for the default and import type for the types (and similarly make PropsOf a type-only import).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/mui-styled-engine/src/GlobalStyles/GlobalStyles.tsx Outdated
@Janpot Janpot force-pushed the code-infra/styled-engine-typescript branch from c379788 to 868dc99 Compare May 20, 2026 09:12
@Janpot Janpot requested a review from Copilot May 20, 2026 10:14
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 19 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

packages/mui-styled-engine/src/StyledEngineProvider/StyledEngineProvider.tsx:126

  • StyledEngineProvider is declared to return React.JSX.Element, but when cache is falsy it returns children (a ReactNode, potentially string | null | undefined | ReactNode[]). The as React.JSX.Element cast masks this mismatch.

Consider always returning an element (e.g. wrap children in a fragment when there is no cache) so the implementation matches the return type without a cast.

@Janpot Janpot marked this pull request as ready for review May 20, 2026 16:08
@Janpot Janpot requested review from a team May 20, 2026 16:10
Copy link
Copy Markdown
Member

@siriwatknp siriwatknp left a comment

Choose a reason for hiding this comment

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

LGTM, one minor comment.

}

return stylesFactory;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
}
} as CreateStyled

Would this work, so that the tag and options does not need any?

Copy link
Copy Markdown
Member Author

@Janpot Janpot May 21, 2026

Choose a reason for hiding this comment

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

That would be invalid on a function declaration. I guess one could convert to an arrow function, but that wouldn't keep the js byte-compatible.

Comment on lines 1 to -2
export { default } from './StyledEngineProvider';
export * from './StyledEngineProvider';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

cant these 2 lines just be -

export * from './StyledEngineProvider';

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

export * from './X' re-exports named exports only, default export is not included in that (according to spec, I'm sure some bundlers do that under some configurations).

@zannager zannager added the scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd). label May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants