Currently, I am developing a client for a web service that has 20 possible parameters (with the potential to increase). Each parameter corresponds to a specific method that needs to be exposed on the client. My current approach is as follows:
// keys.ts
export const FUNCTION_ONE = 'FunctionOne';
export const FUNCTION_TWO = 'FunctionTwo';
...
export const FUNCTION_TWENTY = 'FunctionTwenty';
// client.ts
import * as keys from './keys';
import { camelcase } from 'lodash';
export default class Client {
makeCall(method: string): Promise<void> {
// some implementation
}
}
Object.values(keys).forEach((key) => {
(Client.prototype as any)[camelcase(key)] = function () {
return this.makeCall(key);
};
});
The issue arises where Typescript is unaware of these dynamically added methods. To address this, I am exploring modifying the keys by introducing a typable camelcase form of each key. This trade-off would require manual typing but would streamline adding new methods to the keys.ts file.
My idea involves creating a type that combines the keys with the class to generate an interface containing all method names. A preliminary attempt looks like this:
// keys.ts
function key<T extends string>(command: string, name: T) {
return { command, name };
}
export const FUNCTION_ONE = key('FunctionOne', 'functionOne');
...
// client.ts
export default class Client {
// same as before
}
interface ClientInterface<T extends Record<string, { name: string }>> {
// implementation??
}
export default type Client = ClientInterface<keys>;
How can I construct the ClientInterface
type to automatically generate an interface with all method names from the keys file? Alternatively, is there a more efficient approach to achieve this goal?