I use mongodb with @types/mongodb. This gives me a nice FilterQuery interface for my mogodb queries for a collection of shaped documents. In my domain object class I have some extra logic like converting dates to moment objects or floats to BigNumber objects.
For my queries I need to convert these back, so for example a Moment object needs to be converted to a date object and so on. To avoid duplication and maintaining a separate interface (just for the queries) I thought of using mapped types to replace all types of Moment to type of Date
type DeepReplace<T, Conditon, Replacement> = {
[P in keyof T]: T[P] extends Conditon
? Replacement
: T[P] extends object
? DeepReplace<T[P], Conditon, Replacement>
: T[P];
};
class MyDoaminClass {
date: Moment;
nested: {
date: Moment;
};
}
const query: DeepReplace<MyDoaminClass, Moment, Date> = {
date: moment().toDate(),
nested: {
date: moment().toDate()
}
};
This basically works, but I have about 4-5 of these types that I would need to replace. Is there an elegant way to chain several DeepReplace Types or even better: Specify all type replacements in one place? I would like to avoid something like type ReplaceHell = DeepReplace<DeepReplace<DeepReplace<MyDoaminClass, Moment, Date>, BigNumber, number>, Something, string>