I'll try my best in describing our case, as I have no idea how to title this.
We have a package, which handles requesting our services/cloud functions (if for example service A needs something done by service B, it uses this package). This package exposes a function to call each service (for example for service auth, there would be a auth function exposed. We have a definition of available endpoints for each service and as this grows, it's harder to maintain since we were unable to figure out a way to type the parameters for the requests.
What I wanted to do, is simply have another type which would contain the parameter types for each endpoint of each service.
For example we have endpoint called getEmail, which would return email of a user and requires an id parameter.
Type params type would look like this:
type Params = {
getEmail: {
id: number;
}
}
Very simplified version of the code:
type FunctionName = 'foo' | 'bar' | 'baz';
type FunctionParams = {
foo: {
myVar: number;
};
bar: {
myVar: string;
};
baz: Record<string, number>;
};
declare const sendRequest: (...args: any[]) => any;
const callFunction = (
fn: FunctionName,
params: FunctionParams[typeof fn],
// ^^^^^^^^^ What should I put here?
) => {
sendRequest(fn, params);
};
callFunction('foo', {
myVar: 'this should fail',
// This is allowed, as the type of the second parameter is:
// { myVar: number; } | { myVar: string; } | Record<string, number>) => void
// I want it to be { myVar: number; }
});
You want to use generics! You can parameterize callFunction to bind fn to a specific string, and then use this to index FunctionParams:
function callFunction<T extends FunctionName>(
fn: T,
params: FunctionParams[T],
) {
sendRequest(fn, params);
};
callFunction('foo', {
myVar: 'this should fail', //BOOM!
});
Also, don't waste energy maintaining types. FunctionName can be as easy as
type FunctionName = keyof FunctionParams
with that, every time you add new params, FunctionName gets updated.
See also this playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With