AWS DynamoDB doesn't store Date values, so all date/time values need to be serialized into ISO 8601 strings before storing, and then need to be deserialized from strings to Date when retrieving.
I've created a pair of generic TypeScript helper functions to do this serialization and deserialization. But I'm not sure how to make these functions type-safe. I also don't want to deal with maintaining pairs of normal vs. serialized types-- instead I just want to define the "normal" type and use a generic type definition to define the serialized type.
Specifically, given some type T which may have Date-typed properties (either at top level or in nested objects) I want to create a type definition for Serialized<T> that has the same shape as T except that all Date-typed properties are replaced with string. Is this possible?
For example, given an object that looks like this:
interface OriginalType {
foo: Date,
bar: number,
nested: {
created: Date
}
}
I want to end up with a type like the one below: (but without manually typing in the definition)
interface SerializedType {
foo: string,
bar: number,
nested: {
created: string
}
}
What should be the declaration for Serialized<T>?
You are looking for a recursive homomorphic mapped type (to iterate over the fields) using a conditional type (to check whether each field is a date).
type Serialized<T> = {
[P in keyof T]: T[P] extends Date ? string : Serialized<T[P]>
};
This solution takes advantage of the special rule that applying a homomorphic mapped type such as Serialized to a primitive type returns the primitive type, regardless of the body of the homomorphic mapped type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With