本当にただのメモ

なるべく Qiita に投稿しよう

(調べ途中) TypeScript で JSON の decode/encode するときに暗黙の型変換を行いたい場合

  • JSON では created_at が unix time として返ってくるが
  • これを decode 後は ( created_date という別のプロパティとして) Date 型として扱いたい場合

を例とする。

結論からいうと下記のようになった。

import { plainToClass } from "class-transformer";

class Item {
    private _created_at: number
    created_date: Date

    constructor() { }

    set created_at(utime: number) {
        this._created_at = utime
        this.created_date = new Date(utime * 1000)
    }
    get created_at(): number {
        return this._created_at
    }
}

const json = `[
    { "created_at": 1400000000 },
    { "created_at": 1500000000 }
]`

let parsed: Object
try {
    parsed = JSON.parse(json)
} catch (e) {
    throw new Error(`JSON parse error: ${e}`)
}
const items = plainToClass(Item, parsed) as any as Item[]
console.log(items[0].created_date) //=> Wed May 14 2014 01:53:20 GMT+0900 (JST) 
console.log(items[1].created_date) //=> Fri Jul 14 2017 11:40:00 GMT+0900 (JST)

ポイントは下記で、class-transformerplainToClass() を使うことで、パース結果の配列をループで回して 1 個 1 個 Item オブジェクト化して ... というコードが不要になる。 *1

(参考: class-transformerでpureなjsオブジェクトとクラスとの変換が便利だった - Qiita

困っていること

Class を JSON 化したときに

  • getter の値が JSON に含まれない(まぁ仕方ない気もする。不便だけど)
  • プライベートプロパティが JSON に含まれる(これはどうなの ... )

となるので困っている。

(参考: https://stackoverflow.com/questions/40080473/using-json-stringify-in-conjunction-with-typescript-getter-setter

console.log(JSON.stringify(items[0])
//=> {"_created_at":1400000000,"created_date":"2014-05-13T16:53:20.000Z"}

classToPlain() 使えば良いのか? と思ったが結果変わらず。どういうときに使うんだろうこれ。。

console.log(JSON.stringify(classToPlain(items[0]))
//=> {"_created_at":1400000000,"created_date":"2014-05-13T16:53:20.000Z"}

公式の description をもう少し深く調べられば分かりそうだけど、いったん今はここまで。

*1:多少コードが減る程度で、別に必須ではないと思うものの