-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Labels
help wantedContributions from community are welcomeContributions from community are welcome
Description
Description
When using module augmentation to add type safety to context modals as documented, the modal property in openContextModal() accepts any string instead of being restricted to the defined modal keys. However, innerProps IS correctly type-checked.
Steps to reproduce
- Define modals and augment
MantineModalsOverrideas per docs:
// modals/index.ts
export const modals = {
createDepartment: AddDepartmentModal,
createUser: CreateUserModal,
} as const;
// registry.d.ts
import type { modals } from './modals';
declare module '@mantine/modals' {
export interface MantineModalsOverride {
modals: typeof modals;
}
}
export {};- Call
openContextModalwith an invalid modal name:
openContextModal({
modal: 'invalidModalName', // ❌ No TypeScript error, but should error
title: 'Test',
innerProps: { orgId: 123 },
});- Note that
innerPropsIS type-checked correctly:
openContextModal({
modal: 'createDepartment',
title: 'Test',
innerProps: { wrongProp: 123 }, // ✅ TypeScript error as expected
});Expected behavior
modal: 'invalidModalName' should produce a TypeScript error like:
Type '"invalidModalName"' is not assignable to type '"createDepartment" | "createUser"'
Actual behavior
No error. Any string is accepted for modal.
Root cause analysis
The issue is in context.d.ts:
export type MantineModalsOverwritten = MantineModalsOverride extends {
modals: Record<string, React.FC<ContextModalProps<any>>>;
} ? MantineModalsOverride : {
modals: Record<string, React.FC<ContextModalProps<any>>>;
};
export type MantineModals = MantineModalsOverwritten['modals'];
export type MantineModal = keyof MantineModals;When TypeScript evaluates MantineModalsOverwritten['modals'], it intersects the type with the conditional's constraint (Record<string, ...>), causing keyof to return string instead of the literal union.
Proof:
// Direct access works correctly:
type ModalsDir = MantineModalsOverride['modals'];
type ModalDir = keyof ModalsDir; // "createDepartment" | "createUser" ✓
// Through conditional type doesn't:
type Modals = MantineModalsOverwritten['modals'];
type Modal = keyof Modals; // string ✗Suggested fix
Replace the conditional type pattern with direct property access, or use a different conditional structure that doesn't cause type widening:
// Option 1: Direct access when modals property exists
export type MantineModals = MantineModalsOverride extends { modals: infer M }
? M
: Record<string, React.FC<ContextModalProps<any>>>;
// Option 2: Use a mapped type or other patternEnvironment
@mantine/modals: 8.3.11- TypeScript: 5.9.3
- tsconfig:
moduleResolution: "bundler",strict: false
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
help wantedContributions from community are welcomeContributions from community are welcome