我正在为Web服务编写客户端,并且端点之一从可能的20个参数(可能会增加)中获取一个参数。
我在客户端公开了每种可能性的方法。现在我正在这样做:
// 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);
};
});
Typescript对这些方法一无所知,因为它们是通过编程方式添加的。我不想手动编写每个方法,因为该服务可能会添加更多内容,并且我希望将它们添加到keys.ts文件中很容易。
我当时正在考虑对键进行修改,这将要求我键入键的驼峰形式(可以接受的折衷方案),然后我可以用它来构建可与类结合使用的类型。像这样:
// 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>;
如何编写这种ClientInterface
类型,该类型将使用键中的所有名称作为方法来生成接口?还是有一种更好的方法可以完全做到这一点?
答案 0 :(得分:2)
您可以使用:
type ClientInterface<T extends Record<string, { name: string }>> =
{[N in T[keyof T]["name"]]: () => Promise<void> };
export type ClientType = ClientInterface<typeof keys>;
或者,如果您愿意在驼峰式的情况下实际命名常量,那么它将变得更加简单,并且常量上的“重命名”命令将能够更新所有调用:
type ClientInterface<T> =
{[N in keyof T]: () => Promise<void> };
export type ClientType = ClientInterface<typeof keys>;