I'm trying to construct a map of types and callbacks so I started with an structure like this:
type Instantiable<T = unknown> = new (...args: any[]) => T;
type SingleParamFn<TInput = unknown, TOuput = unknown> = (arg: TInput) => TOuput;
type TypesRecord<T> = { type: Instantiable<T>, callback: SingleParamFn<T> };
type TypesMap = TypesRecord[]; // This is the structure
An example of this:
const myMap: TypesMap = [{ type: Date, callback: (value) => 'this is a Date' }];
This seems works as expected but I realised it is a bit inefficient as you need to loop the array to find the type you want.
I started to play with having the types as object keys and it seems to work at least in Google Chrome:
class MyFancyObject {}
class MyOtherObject {}
const map = {
[Date]: () => 'this is a date',
[MyFancyObject]: () => 'this is a fancy object',
[MyOtherObject]: () => 'this is another object'
};
console.log(map[Date]()); // 'this is a date'
console.log(map[MyFancyObject]()); // 'this is a fancy object'
console.log(map[MyOtherObject]()); // 'this is another object'
const obj = new MyFancyObject();
console.log(map[obj.constructor]()); // 'this is a fancy object'
console.log(map[(new Date()).constructor]()); // 'this is a date'
I've been checking some documentation and it seems like an object's key can only be an string or a Symbol so I checked what constitutes a Symbol and it seems to be a bit vage as it is defined as a built-in object whose constructor returns a symbol primitive that's guaranteed to be unique and an object's constructor is (to the best of my knowledge), unique.
Given all of this, is using the constructors as object keys a reliable approach? If so, how can I define the typescript type for such object? If it isn't, are there other options (like the Map object)?