Suppose I have the following JS code:
export const giveMeFunctions = (namePrefix, number) => {
const functionA = (x) => number + x;
const functionB = (x, y) => number * x - y;
return {
[`${namePrefix}Add`]: functionA,
[`${namePrefix}MultSub`]: functionB,
};
}
// This is handy because I can then do:
const {piAdd, piMultSub} = giveMeFunctions('pi', Math.PI);
const {eAdd, eMultSub} = giveMeFunctions('e', Math.E);
// No confusion between variable names, and object interpolation makes it easy to use
I cannot, however, think of a good way to type the return value of this function in Typescript. As you can see, the two keys have different types, so I can't simply do something like
const giveMeFunctions<N extends string> = (number: number): {
[key: string]: Function;
} => {...}
as this would allow accidental interchanging of the arguments of functionA
and functionB
. It seems logical to me that this should be possible with Typescript, as it's all possible at compile-time. For instance, if we simply took out the concatenation step, this would be easily possible:
export const giveMeFunctions<T extends string> = (number: number): Record<T, string> => {...}
Something I expected to work would be:
const giveMeFunctions<N extends string> = (number: number): {
[N + 'Add']: string,
[N + 'MultSub']: string,
} => {...}
or even:
const giveMeFunctions<N extends string> = (namePrefix: N, number: number): {
[N + 'Add']: string,
[N + 'MultSub']: string,
} => {...}
but both of these complain that:
TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
Is there any way to achieve the desired effect of an object type with keys defined by a concatenation of a user-specified string and a hard-coded suffix?
{ [x: string]: ((x: any) => any) | ((x: any, y: any) => number); }
. You should typenamePrefix
asstring
, changenumber
tovalue
and make the typenumber
, and type your arrow funcitonA,B arguments asnumber
and the return type will then be[x: string]: (x: number, y: number) => number;