Home > other >  How to create a utility type to "serialize" an array of objects in TypeScript?
How to create a utility type to "serialize" an array of objects in TypeScript?

Time:10-03

Let's suppose I have the following object type:

type Test = {
  date: Date
  num: number
  str: string
}

As you can see there is a Date type that I want to convert to a string ("serialize"), so I created the following Generic Type:

type Serializer<T extends {[key: string]: unknown}> = {
  [key in keyof T]: T[key] extends Date ? string : T[key]
}

Which does the job very well, you can check this playground result

But know, what if I have a Test[] type, what generic type could help me "serialize" this data type?

CodePudding user response:

To achieve a serializer generic that takes an array as input, you would require a custom ArrayElement type that would get the type of an element in your array.

Then your serializer has 2 generic types, the array (A) and the array element (T) which is equal to ArrayElement<A>

Here's an example:

type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;

type Serializer<A extends Array<{ [key: string]: unknown }>, T = ArrayElement<A> > = {
  [key in keyof T]: T[key] extends Date ? string : T[key];
};

type Result = Serializer<Test>
//  type Result = {
//     date: string;
//     num: number;
//     str: string;
// }

Edit: You can one line the ArrayElement although I think this gets pretty messy and unreadable.

type Serializer<A extends Array<{ [key: string]: unknown }>, T = A extends readonly (infer T)[] ? T : never > = {
  [key in keyof T]: T[key] extends Date ? string : T[key];
};
  • Related