[code-infra] Convert @mui/styled-engine-sc to TypeScript#48577
Conversation
Same setup as @mui/styled-engine (mui#48544) and @mui/private-theming (mui#48565): hand-written `.js` + `.d.ts` source replaced with a single `.ts`/`.tsx`, declarations now emitted by `tsc` instead of copied, `--skipTsc` dropped from the build script, `tsconfig.build.json` added. This package's hand-written `.d.ts` over-claimed the type surface by re-exporting the entire `styled-components` named-export set via `export * from 'styled-components'`, while the runtime `.js` only re-exported `ThemeContext`, `keyframes`, `css`. To keep the exported type surface 100% identical (proven via a bidirectional type-equivalence probe over root + every subpath entry), the new `src/index.ts` keeps the `export * from 'styled-components'` — so the runtime JS now also re-exports the broader surface, fixing the prior type/runtime divergence. The local default stays the dev-mode wrapper, cast to `typeof scStyled` so its public type matches the hand `.d.ts`'s `export { default } from 'styled-components'`. Other JS deltas are limited to the standard true-TS conversion artifacts: propTypes assignments now wrap in the `process.env.NODE_ENV !== 'production' ? … : void 0` guard via the `/* remove-proptypes */` marker, and `index`'s default export form becomes `function styled; export default styled;` (same runtime). `.d.ts` differences are limited to type-preserving forms (`import type`, `export type *`, `declare`, expando-free default emit). There are no internal MUI workspace consumers of `@mui/styled-engine-sc`, so no downstream `tsconfig.build.json` `references` updates were needed. ## Published artifact diff Diff of the published package before/after this PR: [`@mui/styled-engine-sc`].
Deploy previewhttps://deploy-preview-48577--material-ui.netlify.app/ Bundle size
Check out the code infra dashboard for more information about this PR. |
The TS conversion previously kept `export * from 'styled-components'` to preserve the over-claimed surface of the hand-written `.d.ts`, which broadened the published JS to re-export the entire styled-components surface (`ServerStyleSheet`, `ThemeProvider`, `StyleSheetManager`, …). The hand-written `.d.ts` was a long-standing bug — those symbols resolved to `undefined` at runtime, so no consumer can have been relying on them. The sibling `@mui/styled-engine` (emotion) deliberately does not `export *` either. Narrow the type surface to match the original narrow runtime instead of the other way around: drop the broad re-export and put back the explicit `ThemeContext, keyframes, css` named re-export from the old `index.js`.
Bring back the type half of the original hand-written `.d.ts` via
`export type * from 'styled-components'`. The original split was:
broad types (via `export *` and `export { default } from
'styled-components'` in the `.d.ts`), narrow runtime (only
`ThemeContext, keyframes, css` re-exported in the `.js`). Use a
type-only re-export so the broad surface stays on the type side and
emits nothing at runtime. Local type declarations still shadow the
styled-components ones, as before.
| import PropTypes from 'prop-types'; | ||
| import { createGlobalStyle, type CSSObject, type StyleFunction } from 'styled-components'; | ||
|
|
||
| export interface GlobalStylesProps<Theme extends object = {}> { |
There was a problem hiding this comment.
| export interface GlobalStylesProps<Theme extends object = {}> { | |
| export interface GlobalStylesProps<Theme extends object = Record<string, any>> { |
Is this more accurate? {} could be primitive.
There was a problem hiding this comment.
Maybe, but I'm not planning on changing types in this PR unless strictly necessary for the migration. The goal is migrating to typescript with no impact on exported javascript, and the least possible impact to the exported types. Essentially only fixing bugs in the old handwritten declaration files that can't be expressed exactly in a .ts => .d.ts transformation.
|
|
||
| export default GlobalStyles; | ||
|
|
||
| (GlobalStyles as any).propTypes /* remove-proptypes */ = { |
There was a problem hiding this comment.
I remember from some other code (not sure where) that we also wrap propTypes behind NODE_ENV !== 'production' check.
There was a problem hiding this comment.
/* remove-proptypes */ causes this in the build output
-GlobalStyles.propTypes = {
+process.env.NODE_ENV !== "production" ? GlobalStyles.propTypes /* remove-proptypes */ = {
defaultTheme: _propTypes.default.object,
styles: _propTypes.default.oneOfType([_propTypes.default.array, _propTypes.default.string, _propTypes.default.object, _propTypes.default.func])
-};
+} : void 0;|
Part of the ts-package-migration umbrella: mui/mui-public#1510 |
Converts
@mui/styled-engine-scto true TypeScript (same setup as@mui/utils/@mui/styled-engine/@mui/private-theming): hand-written.js+.d.tssource replaced with.ts/.tsx, declarations now emitted bytsc,--skipTscdropped,tsconfig.build.jsonadded.The hand-written
.d.tsover-claimed the type surface by re-exporting the entirestyled-componentsnamed-export set (export * from 'styled-components') while the runtime.jsonly re-exportedThemeContext,keyframes,css. To keep the exported type surface 100% identical (verified via a bidirectional type-equivalence probe over the root and every subpath entry), the newsrc/index.tskeepsexport * from 'styled-components', so the runtime JS now also re-exports the broader surface — fixing the prior type/runtime divergence rather than narrowing the types to match the runtime. The local default stays the dev-mode wrapper, cast totypeof scStyledso its public type matches the hand.d.ts'sexport { default } from 'styled-components'.Other
.jsdeltas are limited to standard true-TS conversion artifacts: propTypes assignments now wrap inprocess.env.NODE_ENV !== 'production' ? … : void 0via the/* remove-proptypes */marker, andindex's default export form becomesfunction styled; export default styled;(same runtime)..d.tsdifferences are type-preserving forms (import type,export type *,declare).There are no internal MUI workspace consumers of
@mui/styled-engine-sc, so no downstreamtsconfig.build.jsonreferencesupdates were needed.Published artifact diff
https://code-infra-dashboard.onrender.com/diff-package?package1=https%3A%2F%2Fpkg.pr.new%2Fmui%2Fmaterial-ui%2F%40mui%2Fstyled-engine-sc%4074a6177&package2=https%3A%2F%2Fpkg.pr.new%2Fmui%2Fmaterial-ui%2F%40mui%2Fstyled-engine-sc%402f907c1