I need a TypeScript type that copies another object type, but changes type of properties based on their original type condition. And also do so to all nested and deep nested properties.
For example a type DateToStrings<T>
that would turn all type Date
properties into type string
properties. It would look like this:
If I have a class:
class Milk {
brandName: string,
prince: number,
dealExpiredAt: Date,
properties: {
expirationDetails: {
expiredAt: Date
}
}
}
The type DateToStrings<Milk>
would be:
{
brandName: string,
price: number,
dealExpiredAt: string,
properties: {
expirationDetails: {
expiredAt: string
}
}
}
Would really appreciate some help as I don't really have a direction to approach it, any tips or known types / type packages that do something similar?
CodePudding user response:
You could use recursive conditional type. Not all edge cases covered, but for above example something like this should work:
type DateToStrings<T> = {
[K in keyof T]: T[K] extends Date
? string
: T[K] extends Array<infer I>
? Array<DateToStrings<I>>
: T[K] extends object
? DateToStrings<T[K]>
: T[K]
}
type MilkTransformed = DateToStrings<Milk>
const foo: MilkTransformed = {
brandName: 'string',
prince: 123,
dealExpiredAt: 'Date',
properties: {
expirationDetails: {
// Expected error: Type 'Date' is not assignable to type 'string'
expiredAt: new Date
}
}
}