danvk / effective-typescript

Effective TypeScript 2nd Edition: 83 Specific Ways to Improve Your TypeScript
https://effectivetypescript.com
Other
1.53k stars 226 forks source link

What's the type of JSON.parse(​JSON.stringify(x))? #7

Open danvk opened 2 years ago

danvk commented 2 years ago

What's the type of JSON.parse(​JSON.stringify(x))?

https://effectivetypescript.com/2020/04/09/jsonify/

danvk commented 2 years ago

Comment by Ramiro on 2021-01-19 11:55:

here more pulished


type toJSON<t> =
T extends { toJSON: (...args: any) => infer R } ? toJSON<r> :
T extends Array<infer i=""> ? Array<tojson<i>> :
T extends (...args: any) => any ? never :
T extends object ? { [K in keyof T]: K extends string | number ? toJSON<t[k]> : never } :
T;

jeremyhewett commented 1 month ago

Taking it a bit further:

type Deserialized<T> = 
  unknown extends T ? unknown :
  T extends JSONPrimitive ? T :
  T extends { toJSON: () => infer R } ? Deserialized<R> :
  [] extends T ? Deserialized<T[number]>[] :
  T extends object ? DeserializedObject<T> :
  never;

type DeserializedObject<T extends object> = {
  [K in keyof T as T[K] extends NotAssignableToJson ? never : K]: Deserialized<T[K]>;
};

type JSONPrimitive = string | number | boolean | null | undefined;
type NotAssignableToJson = bigint | symbol | ((...args: any) => unknown);

https://gist.github.com/jeremyhewett/48a82d3a63413496000471fe734dfe6b