Description
Current Behavior
dist/index.d.ts re-exports DateTimePickerProps from @mui/x-date-pickers/DateTimePicker:
import { DateTimePickerProps } from '@mui/x-date-pickers/DateTimePicker';
export { DateTimePickerProps } from '@mui/x-date-pickers/DateTimePicker';@mui/x-date-pickers is declared optional under peerDependenciesMeta, so a consumer is
entitled to skip it. When they do, that reference does not resolve and the type quietly collapses:
skipLibCheck: false->TS2307: Cannot find module '@mui/x-date-pickers/DateTimePicker',
pointing at sistent's own.d.tsrather than at the package actually missing;skipLibCheck: true(the common default) ->DateTimePickerPropssilently becomesany.
Reproduced against a clean consumer with the optional peer absent - this probe compiles, which
it only can if the type degraded to any:
import type { DateTimePickerProps } from '@sistent/sistent';
type IsAny<T> = 0 extends (1 & T) ? true : false;
export const p: IsAny<DateTimePickerProps> = true;Expected Behavior
Either the type does not appear in the barrel's public surface at all, or it resolves for every
consumer. A public type must not depend on a package the consumer was explicitly told is optional.
Context
This is the declaration-side twin of the optional-peer rule already documented in AGENTS.md
("The barrel must not require an optional peer"). The two fail in opposite directions: that one is
broken by a runtime import, this one by a type re-export - and import type being erased at
runtime is exactly why the existing runtime guard cannot see it.
DateTimePicker itself is correct here: it defers the runtime import via React.lazy
(src/base/DateTimePicker/DateTimePicker.tsx), which is the documented fix for the runtime half.
Only the type re-export is left over.
Discovered while fixing the same class of defect for @meshery/schemas, whose Key type was
degrading to any the same way. That fix landed with a guard,
src/__testing__/publishedTypeSurfaceDependencies.test.ts, which asserts that every external
package named by the built dist/index.d.ts is a real dependency or peerDependency.
@mui/x-date-pickers is currently exempted on the record in that guard's optional-peer
exemption list, pointing at this issue - so the guard stays honest about the hole instead of
hiding it.
Suggested fix
Preferred: stop re-exporting DateTimePickerProps from the root barrel, so the optional peer stops
being part of the published type surface.
Alternatives considered and not chosen:
- Promote
@mui/x-date-pickersto a required peer - contradicts the optional-peer contract and the
direction of Barrel import still requires the optional peer date-fns (UniversalFilter), breaking clean-install consumers #1735. - Leave it exempted permanently - keeps a public type that is
anyfor anyone who took the package
at its word that the peer is optional.
Once resolved, delete the @mui/x-date-pickers entry from OPTIONAL_PEERS_ON_THE_RECORD in
src/__testing__/publishedTypeSurfaceDependencies.test.ts; the guard asserts each exemption is
still needed, so a stale entry fails the test rather than lingering.
Activity
Valyrian-Code commentedon Jul 26, 2026
@chellej I'd like to work on this one, could you assign it to me?
One thing I hit while reproducing it: removing the
export type { DateTimePickerProps }fromsrc/base/DateTimePicker/index.tsxisn't enough on its own. I tried exactly that and rebuilt, anddist/index.d.tsstill hasbecause the exported component is itself declared with that type:
so the import survives to serve that declaration. It goes 2 references -> 1, not 0, which means the
@mui/x-date-pickersentry inOPTIONAL_PEERS_ON_THE_RECORDstill can't be deleted (the guard asserts each exemption is still needed, so it'd have to stay).So the props type the component is declared with has to stop naming the peer too, not just the re-export. The way that keeps the public API intact, as far as I can tell, is a local props type in sistent for the wrapper's own surface, with the real MUI type used only inside the implementation where the declaration bundle doesn't emit it.
Happy to go that way, but since it touches the public shape of
DateTimePickerPropsI'd rather check the direction with you before writing it. Is the local-type approach what you had in mind, or would you prefer the picker move behind its own entry point?