とあるオブジェクトを JSON.stringify してできた文字列をさらに JSON.parse してできるオブジェクトの型の宣言したい場合には、以下のように Mapped types を利用することで元のオブジェクトの型から型を生成することができます。
type Jsonize<T> = {
[P in keyof T]: T[P] extends Date
? string
: T[P] extends Array<infer U>
? Array<Jsonize<U>>
: T[P] extends object
? Jsonize<T[P]>
: T[P]
};
Date 型は string に変換し、配列は要素の型を再帰的に変換、それ以外のオブジェクトはプリミティブになるまで再帰的に変換する形です。
利用例は以下のようになります。
interface Simple {
str: string;
num: number;
bool: boolean;
nul: null;
date: Date;
}
interface Complex extends Simple {
obj: Simple,
array: Simple[];
optional?: Simple;
}
type Jsonized = Jsonize<Complex>;
const jsonized: Jsonized = {
obj: {
str: '',
num: 0,
bool: true,
nul: null,
date: '',
},
str: '',
num: 0,
bool: true,
nul: null,
date: '',
array: [{
str: '',
num: 0,
bool: true,
nul: null,
date: '',
}],
optional: undefined,
};