typescript-modulförstärkning med härledd typ
Jag hoppas att någon kan hjälpa mig med detta. Jag skapar ett designsystem och har därför 2 repos: react-komponentbiblioteket och applikationen som använder det. I react-biblioteket exporterar jag en createTheme-funktion som applikationen kan använda för att skapa sitt tema:
// library
export const createTheme(options) => { ... }
// application
import {createTheme} from 'library';
export const theme = createTheme( ... );
Komponentens props är typade genom att använda en DefaultTheme-typ i biblioteket. Detta gör det möjligt för användarna av biblioteket att definiera några varianter eller storlekar i ett globalt tema. till exempel:
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>)
}
Nu vill jag kunna ställa in de korrekta typerna i applikationen genom att använda modulaugumentering i TypeScript för DefaultTheme-typen:
import 'library';
declare module 'library' {
export interface DefaultTheme {
components: {
SomeComp: {
props: {
size: {
small: 'small';
medium: 'medium';
large: 'large';
};
};
};
};
}
}
Detta fungerar utan problem! Men jag vill använda typen av returvärdet från createTheme-funktionen, så jag inte behöver skriva det två gånger. Detta är vad jag vill:
import 'library';
import {CustomApplicationTheme} from './theme';
declare module 'library' {
export interface DefaultTheme extends CustomApplicationTheme {}
}
När jag gör detta visas inga fel, men typen av size-egenskapen på SomeComp faller alltid tillbaka på bibliotekets DefaultTheme:
// 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. Varför kan jag inte använda en härledd typ för modulförstärkning?
Jag försökte också använda en typ istället för ett gränssnitt för module augmentation, men då får jag följande felmeddelande:
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;
}
Faktiskt skulle jag föredra att använda en typ istället för ett gränssnitt. Jag skulle vara mycket glad över hjälp. Tack.