1 year ago
#87275
jarvispact
typescript module augmentation with inferred type
i hope someone can help me with this. I am creating a design system and therefor have 2 repos: the react component library and the application that consumes it. In the react library i am exporting a createTheme
function which the application can use to create its theme:
// library
export const createTheme(options) => { ... }
// application
import {createTheme} from 'library';
export const theme = createTheme( ... );
The component props are typed by using a DefaultTheme
type in the library. This allows the cnsumers of the library to define some variants or sizes in a global theme. for example:
export type ComponentProps = {
// looks like this in the DefaultTheme: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl"
size?: keyof DefaultTheme['components']['SomeComp']['props']['size'];
};
export const SomeComp = () => {
const theme = useTheme();
const className = doSomethingWithContext(theme);
return (<div className={className}>something</div>)
}
Now i want to be able to setup the correct types in the application by using module augmentation in typescript for the DefaultTheme
type:
import 'library';
declare module 'library' {
export interface DefaultTheme {
components: {
SomeComp: {
props: {
size: {
small: 'small';
medium: 'medium';
large: 'large';
};
};
};
};
}
}
This works without any problem! But i want to use the type of the return value of the createTheme function, so i dont have to write it twice. This is want i want:
import 'library';
import {CustomApplicationTheme} from './theme';
declare module 'library' {
export interface DefaultTheme extends CustomApplicationTheme {}
}
When i do this, it shows no errors but the type of the size
prop of SomeComp
always falls back to the DefaultTheme of the library:
// size should be of the type: 'small' | 'medium' | 'large'
// but ts says it should be of type: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl"
// so i get a type error for the size property
<SomeComp as="h1" size="small">Hello world</SomeComp>
1. Why do i cannot use a inferred type for module augmentation?
Also i tried to use a type instead of an interface for module augmentation, but then i get the following error message:
import 'library';
import { theme } from './theme';
declare module 'library' {
// Duplicate identifier 'DefaultTheme'.ts(2300)
// default-theme.d.ts(48, 21): 'DefaultTheme' was also declared here
export type DefaultTheme = typeof theme;
}
Actually i would prefer using a type instead of an interface. I would be very happy about help. Thank you.
typescript
module-augmentation
0 Answers
Your Answer