[Typescript] Identity function pattern - Using Identity function to enforce the type 01
So we have the configObj look like this:
export const configObj = {
routes: ["/", "/about", "/contact"],
fetchers: {
// @ts-expect-error
"/does-not-exist": () => {
return {};
},
},
};
The problelm is that for fetchers
, you can name the key which not in the routes
.
We want to enforce the type safety so that the key in fetchers
must present in routes
.
To do that using identity function is good option. Because it return what pass in, so it doesn't change the value. But we can add type checking in order to enforce the type.
The beautiful part of identity function is that it will be removed by most minifer tool, so it won't cause any runtime overhead.
Solution with indetity function:
// Typescript will infer `routes`
// function makeConfig<"/" | "/about" | "/contact">(config: ConfigObj<"/" | "/about" | "/contact">): ConfigObj<"/" | "/about" | "/contact">
type ConfigObj<TRoute extends string> = {
routes: TRoute[];
fetchers: {
[Key in TRoute]: any;
};
};
function makeConfig<TRoute extends string>(config: ConfigObj<TRoute>) {
return config;
}
export const configObj = makeConfig({
routes: ['/', '/about', '/contact'],
fetchers: {
// @ts-expect-error
'/does-not-exist': () => {
return {};
},
},
});
Solution 2:
function makeConfigObj<Route extends string>(config: {
routes: Route[];
fetchers: { [Key in Route]: () => void };
}) {
return config;
}
export const configObj = makeConfigObj({
routes: ['/', '/about', '/contact'],
fetchers: {
// @ts-expect-error
'/does-not-exist': () => {
return {};
},
},
});