Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript convert all date from interface to string

Is it possible to transform all the Date types definition from my interface to string, as it get automatically transformed to string on JSON stringify.

interface Item {
   key: string;
   value: number;
   created: Date;
}

const item: Item = { key: 'abc', value: 1, created: Date() };

// convert to JSON
const itemJson = JSON.stringify(item);

// convert back itemJson to an object
const item2 = JSON.parse(itemJson);

// item2 is not of type `Item` as JSON.stringify convert Dates to strings
// so item2 is of type: { key: string; value: number; created: string; }

Would there be a kind of feature to transform the Date type from my interface to string? Something like const item2: ToJSON<Item> = JSON.parse(itemJson);

Note: I don't want to transform back item2.created to Date but I want to create a new interface corresponding to the conversion item to item2. So item is different of item2 and should stay different, therefor I need a new interface for item2. Of course, I could do it manually, but I have a bunch of interface to convert, I would like to do this with something similar to a utility type: https://www.typescriptlang.org/docs/handbook/utility-types.html

Note2: The goal is to get a new interface called Item2

interface Item2 {
   key: string;
   value: number;
   created: string;
}

Something like type Item2 = ToJSON<Item>.

like image 826
Alexandre Avatar asked Mar 22 '26 09:03

Alexandre


2 Answers

TypeScript type system FTW:

interface Item {
  key: string;
  value: number;
  created: Date;
}

type SwapDatesWithStrings<T> = {
  [k in keyof(T)]: (T[k] extends Date ? string : T[k]);
}

type JsonItems = SwapDatesWithStrings<Item>;

// JsonItems is the same as:
// interface JsonItems {
//   key: string;
//   value: number;
//   created: string;
// }

It works deriving a generic type SwapDatesWithStrings from the base type T, with the same set of properties of T, but with a twist on the property type: properties deriving from Date are converted to strings.

like image 92
A. Chiesa Avatar answered Mar 24 '26 23:03

A. Chiesa


Extending on @alberto-chiesa's answer, we can make it convert dates which are in a nested section of the object and also allow for optional values too:

export interface Item {
    myDate: Date;
    dateRange: {
        start?: Date;
        end: Date;
    };
}

type NestedSwapDatesWithStrings<T> = {
    [k in keyof T]: T[k] extends Date | undefined
        ? string
        : T[k] extends object
        ? NestedSwapDatesWithStrings<T[k]>
        : T[k];
};

type ItemWithStringDates = NestedSwapDatesWithStrings<Item>;

// Result:
// {
//    myDate: string;
//    dateRange: {
//        start: string | undefined;
//        end: string;
//    };
// }

It essentially recursively tries to convert Dates to strings

like image 40
Dolan Avatar answered Mar 24 '26 23:03

Dolan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!