fp-ts
やio-ts
の概要を知っている方向けです.
結論
日付情報が必ず文字列で表現されるのであれば, io-ts-types
で提供されているDateFromISOString
を使いましょう.
(日付情報がDate型で表現される場合がダメな理由は下の方を見てください)
import * as t from "io-ts"
import * as tt from "io-ts-types"
const UserCodec = t.type({
id: t.number,
name: t.string,
createdAt: tt.DateFromISOString,
updatedAt: tt.DateFromISOString,
})
type User = t.TypeOf<typeof UserCodec>
/**
* type User = {
* id: number
* name: string
* createdAt: Date
* updatedAt: Date
* }
*/
// ex
const inputValue = {
id: 3,
name: "るりと",
createdAt: "2021-03-25T14:48:38.401Z",
updatedAt: "2022-03-25T17:42:38.401Z",
}
console.log(UserCodec.decode(inputValue))
/**
* {
* _tag: "Right"
* right: { id: 3, name: "るりと", createdAt: Wed Mar 16 2022 02:42:38 GMT+0900 (日本標準時)・・・ }
* }
*/
本題
普通のDate
型であれば、io-ts-types
にて提供されているdate
を用いれば型チェックが出来ます. しかしながら, JSONなどに日付情報が文字列として埋め込まれている状態に対してはdate
を用いても弾かれてしまいます.
import * as tt from 'io-ts-types'
import * as E from 'fp-ts/Either'
// Date型で日付が表現される場合は通る
const date = new Date(1973, 10, 30)
assert.deepStrictEqual(tt.date.decode(date), E.right(date))
// 文字列で日付が表現される場合は弾かれる
const input = date.toISOString()
assert.deepStrictEqual(tt.date.decode(input), E.left(date))
ここでio-ts-types
にて提供されているDateFromISOString
を用いることによって, 文字列としての日付情報をDate
型として型チェックすることが出来ます.
import * as tt from 'io-ts-types'
import * as E from 'fp-ts/Either'
const date = new Date(1973, 10, 30)
const input = date.toISOString()
assert.deepStrictEqual(tt.DateFromISOString.decode(input), E.right(date))
注意点
Date
型で表現される日付情報をDateFromISOString
で型チェックしようとすると弾かれます.
import * as tt from 'io-ts-types'
import * as E from 'fp-ts/Either'
const date = new Date(1973, 10, 30)
assert.deepStrictEqual(tt.DateFromISOString.decode(input), E.left(date))