I'm currently developing a module where users can specify a list of "allowable types" to be utilized in other functions. However, I'm encountering challenges implementing this feature effectively with TypeScript:
function initializeModule<T extends ArrayLike<string>>(types:T) {
type CustomType = T[number];
function performAction(type:CustomType) {
console.log(type, types);
}
return { performAction, types };
}
// It is desired for this to raise an error: 'potato' is not included in ['hello', 'bye']
initializeModule(['hello', 'bye']).performAction('potato');
I'm aware of the technique that converts an array of strings into a const to create a string literal union type:
const types = ['hello', 'bye'] as const
type CustomType = typeof types[number]
but I am unsure how to apply this concept to my situation, where the array is generic
I have found a solution that works, albeit it feels unconventional: I leverage keyof
to transform T
into a map of <eventType, any>.
function initializeModule<T>(types:(keyof T)[]) {
type CustomType = keyof T;
function performAction(type:CustomType) {
console.log(type, types);
}
return { performAction, types };
}
// As expected, I receive the following error. This is perfect!
// Argument of type '"potato"' is not assignable to parameter of type '"hello" | "bye"'.
initializeModule(['hello', 'bye']).performAction('potato');
Is there a cleaner way to achieve the same outcome without relying on the unconventional keyof
approach and directly creating a union of string literals from the array?