Yimin
Yimin

Reputation: 365

Typescript: Converting typescript interface to a type that represents what it would be after a json.stringify

Say I have a simple interface:

interface Calendar {
  dates: Date[]
  add: () => {}
}

If a calendar object gets Json.stringified, the type becomes like this:

interface StringifiedCalendar {
  dates: string[]
  // Function would dissappear
}

Is there a simple way to convert between the original interface to the stringified version easily? My use case is that rest API would stringify objects, and I'd like to reuse the original type definitions from the backend without rewriting.

Upvotes: 0

Views: 720

Answers (2)

wickning1
wickning1

Reputation: 1

md2perpe's answer was amazingly helpful. I modified it slightly to work with optional Date properties:

type Jsonized<T> = T extends object ? {
  [K in keyof T]:
  T[K] extends Function ? never :
    T[K] extends Date ? string :
      T[K] extends (Date | undefined) ? string | undefined :
        T[K] extends number ? number :
          T[K] extends string ? string :
            Jsonized<T[K]>
} : T

Upvotes: 0

md2perpe
md2perpe

Reputation: 3081

This is at least a partial solution. The editor on the playground still reports that jcal has an add property, but if one tries to use it as a method, an error is reported.

interface Calendar {
  dates: Date[]
  add: () => {}
}

type Jsonized<T> = T extends object ? {
    [K in keyof T]: 
        T[K] extends Function ? never : 
        T[K] extends Date ? string :
        T[K] extends number ? number :
        T[K] extends string ? string :
        Jsonized<T[K]>
} : T;

declare let jcal: Jsonized<Calendar>;
jcal.add();

Playground

Upvotes: 2

Related Questions