I would like to write a function that allows me to cast all object properties (I only have plain objects) to specific type. For the time being I only want to cast to primitives boolean, string and number. Something along these lines:
function castMembers<TObject extends object, TValue extends boolean | string | number>(instance: TObject, type: TValue): Record<keyof TObject, TValue> {
Object.keys(instance).reduce((result, k) => {
// ERROR
result[k] = new type(instance[k]).valueOf();
return result;
}, {});
}
In the future I may extend my casting to some whatever type as long as it satisfies my interface definition which would define that it must include valueOf function. So...
I'm well aware that I can't really instantiate new objects based on generic types, as they're only for compile time. That's why I added the second parameter so I can provide constructor function that should be used for casting. But Im getting an error, or I invalidly wrote my TValue generic param or the type of my second parameter.
How to write such a function?
Edit
I've tried introducing a constructor interface, which gets me very close but I still get an error:
interface IConstructor<TValue> {
new(value?: any): TValue;
}
function castMembers<TObject extends object, TValue extends number | string | boolean>(instance: TObject, toType: IConstructor<TValue>): Record<keyof TObject, TValue> | never {
return (Object.keys(instance) as (keyof TObject)[]).reduce((result, key) => {
result[key] = new toType(instance[key]).valueOf() as TValue;
return result;
}, {} as Record<keyof TObject, TValue>);
}