我想为 JavaScript 库编写类型,该库根据传递给它的字符串创建函数对象。
该函数应该是这样的:
function createResource(name: string): { /* How to write these types? */ } {
return {
[`create${name}`]: () => {},
[`update${name}`]: () => {},
}
}
这个想法是,给一个函数一个字符串(比如“todo”),该函数将返回一个对象
{
createTodo: (todo: Todo) => void,
updateTodo: (todo: Todo) => void
}
最佳答案
如果/当 microsoft/TypeScript#40336合并到 master 中(希望适用于 TS4.1),您将能够使用模板字符串类型来表示连接 "create"
和 "update 时发生的情况"
到为 name
传入的字符串。它看起来有点像这样:
function createResource<T extends string>(name: T) {
return {
[`create${name}`]: () => { },
[`update${name}`]: () => { },
} as { [K in `${"create" | "update"}${T}`]: () => void };
}
它会产生如下输出:
const resource = createResource("Todo");
/* const resource: {
createTodo: () => void;
updateTodo: () => void;
} */
请注意,`create${name}`
不会生成 "createTodo"
,除非 name
是 "Todo"
带有大写的 “T”
。可以使用 capitalize
修饰符将类型系统中的 "todo"
转换为 "Todo"
,但您的实现还需要改变...类似:
const cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
function createResource2<T extends string>(name: T) {
return {
[`create${cap(name)}`]: () => { },
[`update${cap(name)}`]: () => { },
} as { [K in `${"create" | "update"}${capitalize T}`]: () => void };
}
const resource2 = createResource2("todo");
/* const resource2: {
createTodo: () => void;
updateTodo: () => void;
} */
关于Typescript:函数返回类型取决于字符串参数的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55346208/