Skip to content

Instantly share code, notes, and snippets.

@b123400
Created August 8, 2019 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save b123400/43317d58da66d6294f8f65b0ebc1166f to your computer and use it in GitHub Desktop.
Save b123400/43317d58da66d6294f8f65b0ebc1166f to your computer and use it in GitHub Desktop.
type AsJSON<T> =
T extends Date ? string :
T extends Function ? undefined :
T extends Symbol ? undefined :
T extends Array<any> ? AsJSONArray<T> :
T extends object ? AsJSONObj<T> :
T;
type AsJSONObj<T extends object> = {
[K in keyof T]: AsJSON<T[K]>
};
type Inspect<T extends Array<any>> = T extends Array<infer X> ? X : never;
interface AsJSONArray<T extends Array<any>> extends Array<AsJSON<Inspect<T>>> {}
type InvalidKeys<T> = {[K in keyof T]: AsJSON<T[K]> extends undefined ? K : never}[keyof T];
type JSONable<T> = InvalidKeys<T> extends never ? T : ObjectContainsInvalidKeys<InvalidKeys<T>>;
type ObjectContainsInvalidKeys<T> = {_:void}
type User = {
age: number,
name: string,
hi: ()=> void,
createdAt: Date,
friends: User[]
}
function userFromJSON(v: AsJSON<User>): User {
return {
age: v.age,
name: v.name,
createdAt: new Date(v.createdAt),
hi: ()=>{},
friends: v.friends.map(userFromJSON)
}
}
function safeToJSON<T>(v: JSONable<T>): string {
return JSON.stringify(v);
}
safeToJSON({hi: 1});
safeToJSON({good: 'string'});
safeToJSON({foo: ()=>{}, bar: 1});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment