In what follows I'm only concerned with the call signature of addCommands(), not its implementation. That call signature should look like:
declare const addCommands: <N extends string, T extends Record<string, any>>(
name: N, myFunctions: T
) => { [K in (string & keyof T) as `${N}_${K}`]: T[K]; }
This is using key remapping in mapped types via as to convert each string-valued key K in the keys of T to a version prepended with the type of name and an underscore. Since name is of type N, the new key type is the template literal type `${N}_${K}`.
Note that if you just write {[K in keyof T as `${N}_${K}`]: T[K]} you get an error that K can't appear in a template literal type. That's because, in general, the keys you get from the keyof operator are some subtype of PropertyKey, and these include symbol-valued keys, which TypeScript doesn't want to let you serialize (after all, an actual template literal value would produce a runtime error if you tried to do that).
To prevent that error we can restrict the keys over which K ranges. One way is to intersect keyof T with string, like (string & keyof T), to get just the string-valued keys. You could write ((string | number) & keyof T) if you want to support number keys (so that {0: ""} gets mapped to {test_0} instead of {}). Or Exclude<keyof T, symbol> using the Exclude<T, U> utility type, et cetera. The point is to convince the compiler that you're not going to try to serialize any symbols.
Let's test it:
const testFunctions = {
test: () => 'test',
test2: (yo: string) => console.log('test2')
}
const mappedCommands = addCommands('testing', testFunctions);
/* const mappedCommands: {
testing_test: () => string;
testing_test2: (yo: string) => void;
} */
Looks good, that's the type you wanted.
Playground link to code
anyinside the function so there are no compiler errors)... but the return value and type are what you want. If that fully addresses the question I can write up an answer explaining; if not, what am I missing? (Pls mention @jcalz in your reply to notify me)in stringI had errors to do with key not being a string. Thank you