I'd like to write types for a JavaScript library that creates an object of functions depending on a string that is passed to it.
The function is supposed to be something like this:
function createResource(name: string): { /* How to write these types? */ } {
return {
[`create${name}`]: () => {},
[`update${name}`]: () => {},
}
}
The idea is that given a string to a function (say "todo"), the function would return an object
{
createTodo: (todo: Todo) => void,
updateTodo: (todo: Todo) => void
}
If/when microsoft/TypeScript#40336 is merged into master (hopefully for TS4.1) you will be able to use template string types to represent what happens when you concatenate "create"
and "update"
to the string passed in for name
. It will look kind of like this:
function createResource<T extends string>(name: T) {
return {
[`create${name}`]: () => { },
[`update${name}`]: () => { },
} as { [K in `${"create" | "update"}${T}`]: () => void };
}
which produces an output like this:
const resource = createResource("Todo");
/* const resource: {
createTodo: () => void;
updateTodo: () => void;
} */
Note that `create${name}`
does not produce "createTodo"
unless name
is "Todo"
with a capital "T"
. It is possible to use the capitalize
modifier to turn "todo"
into "Todo"
in the type system, but your implementation would also need to change... something like:
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;
} */
Just define the object with implementations (I assume you would like to replace void
with an actual implementation or a function call):
const functions = {
createTodo: (todo: Todo) => void,
updateTodo: (todo: Todo) => void
}
and then your createResource
func will look like that:
function createResource(name: string) {
const createFuncName = `create${name}`
const updateFuncName = `update${name}`
return {
[createFuncName]: functions[createFuncName],
[updateFuncName]: functions[updateFuncName]
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.