java
だとよくやるマッピングのお話。Typescript
を使っているので型の恩恵を受けたい!ということでJSON形式のAPIの戻りを任意のクラスにマッピングしてみる。
object-mapper.ts
export default class ObjectMapper{
private static DEFAULT_MAPPER:(string,any)=>any = (s:string,a:any)=>null
static fromJson<T>(type:{new ():T},json:any,mapper:(string,any)=>any = ObjectMapper.DEFAULT_MAPPER):T{
let instance = new type()
for (var key in json) {
if (instance.hasOwnProperty(key) && json[key] != null && json[key] != undefined) {
let obj = mapper(key,json[key])
if(obj){
instance[key] = obj
}else{
instance[key] = json[key]
}
}
}
return instance
}
}
同名プロパティをそのままマッピングする。入れ子になっているクラスはmapperでインスタンスを作成して返す。名前が違うプロパティのときもmapperを使う。
タイプの指定方法が少し特殊。
let res = ...//APIの戻り
ObjectMapper.fromJson(Category, res , (key:string, value:any) => {
if(key === 'sub_category'){
return SubCategory.from(value)
}
return null
})
・hasOwnProperty
で余計なプロパティが生えないようにしているつもりだが、マッピング対象のクラスのプロパティを初期化しておかないと何も追加されないので注意!
・入れ子をマッピングするプロパティを知っているのはそのクラスなのでファクトリメソッド作るのがいいかも。そうすれば使う側はHoge.from(res)
とかで済むので。
・判定の部分が雑なので治す。