class-transformer を駆使!TypeScript で JSON をクラスインスタンスにスマート変換
JSON から TypeScript クラスインスタンスへのデシリアライズ
JSON.parse と手動のマッピング
最もシンプルな方法は、組み込みの JSON.parse
関数を使用して JSON 文字列を JavaScript オブジェクトに変換し、その後、手動でクラスのプロパティに値をマッピングする方法です。
class User {
id: number;
name: string;
email: string;
}
const jsonString = '{ "id": 1, "name": "Taro Yamada", "email": "[email protected]" }';
const parsedObject = JSON.parse(jsonString);
const user: User = {
id: parsedObject.id,
name: parsedObject.name,
email: parsedObject.email
};
console.log(user); // { id: 1, name: 'Taro Yamada', email: '[email protected]' }
この方法の利点はシンプルで分かりやすいことです。一方、欠点としては、クラスのプロパティと JSON のキー名が一致している必要があること、および、新しいプロパティを追加するたびに手動でマッピングコードを修正する必要があることが挙げられます。
ライブラリの利用
JSON のデシリアライズを容易にするライブラリを多数利用することができます。代表的なライブラリとしては、以下のようなものがあります。
これらのライブラリを利用することで、クラスのプロパティと JSON のキー名を一致させる必要がなくなり、また、新しいプロパティを追加してもコードを修正する必要がなくなります。
class-transformer を利用した例
import { deserialize } from 'class-transformer';
class User {
@Expose()
id: number;
@Expose()
name: string;
@Expose()
email: string;
}
const jsonString = '{ "id": 1, "name": "Taro Yamada", "email": "[email protected]" }';
const user = deserialize(jsonString, User);
console.log(user); // { id: 1, name: 'Taro Yamada', email: '[email protected]' }
どの方法を選択するかは、プロジェクトの要件や開発者の好みによって異なります。シンプルで分かりやすい方法であれば JSON.parse
と手動のマッピング、より柔軟で保守性の高い方法であればライブラリの利用がおすすめです。
- TypeScript のジェネリック型と型推論を活用することで、より汎用的なデシリアライズ処理を書くことができます。
- JSON のスキーマを事前に定義しておくと、デシリアライズ処理のエラーチェックを容易にすることができます。
ライブラリのインストール
npm install class-transformer
コード
import { deserialize } from 'class-transformer';
class User {
@Expose()
id: number;
@Expose()
name: string;
@Expose()
email: string;
}
const jsonString = '{ "id": 1, "name": "Taro Yamada", "email": "[email protected]" }';
const user = deserialize(jsonString, User);
console.log(user); // { id: 1, name: 'Taro Yamada', email: '[email protected]' }
解説
User
クラスを定義します。このクラスには、id
、name
、email
という 3 つのプロパティがあります。@Expose
デコレータを使用して、これらのプロパティが JSON キーとマッピングされることを示します。jsonString
変数に、JSON 文字列を格納します。deserialize
関数を使用して、jsonString
をUser
クラスのインスタンスにデシリアライズします。user
変数に、デシリアライズされたインスタンスを格納します。console.log
を使用して、user
インスタンスの内容を出力します。
このコードは、JSON 文字列を User
クラスのインスタンスにデシリアライズする方法の例です。実際のコードでは、使用するクラスや JSON の構造に合わせて、コードを適宜変更する必要があります。
JSON から TypeScript クラスインスタンスをデシリアライズするその他の方法
- JSON.parse と手動のマッピング
- ライブラリの利用
上記に加え、以下のような方法も検討できます。
- TypeScript のジェネリック型と型推論を活用する
- JSON のスキーマを事前に定義する
interface User {
id: number;
name: string;
email: string;
}
const jsonString = '{ "id": 1, "name": "Taro Yamada", "email": "[email protected]" }';
const user: User = JSON.parse(jsonString);
console.log(user); // { id: 1, name: 'Taro Yamada', email: '[email protected]' }
この例では、User
インターフェースを定義し、JSON オブジェクトの構造を型定義しています。JSON.parse
関数は、ジェネリック型パラメータ T
を指定することで、T
型のオブジェクトを返します。このため、user
変数には、User
型のオブジェクトが格納されます。
この方法の利点は、コードが簡潔になり、型安全性が向上することです。一方、欠点としては、JSON.parse
関数の戻り値の型を推論するためには、JSON の構造が一定である必要があることが挙げられます。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "User schema",
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
}
},
"required": ["id", "name", "email"]
}
この例では、JSON スキーマファイル (例: user.schema.json
) を定義し、User
オブジェクトの構造を記述しています。JSON スキーマバリデーターライブラリ (例: ajv
) を利用することで、JSON 文字列がスキーマに準拠しているかどうかを検証することができます。
この方法の利点は、JSON の構造を厳密に定義し、デシリアライズ処理のエラーを早期に発見することができることです。一方、欠点としては、スキーマファイルの定義とメンテナンスが必要になることが挙げられます。
JSON から TypeScript クラスインスタンスをデシリアライズする方法には、様々な選択肢があります。それぞれの方法には、利点と欠点があるため、プロジェクトの要件や開発者の好みによって最適な方法を選択する必要があります。
json typescript deserialization