DEV Community

e_ntyo
e_ntyo

Posted on

TypeORMにおいて、`date` は `Date` でなく `string` にmapされるので気をつけましょう

tl; dr

TypeORMで Entity を定義する際、日付時刻 (datetime) ではなく 日付 (date) を格納したいと考えている場合はこの記事のことを思い出してください。TypeORMの内部では、DBMSの date からJavaScriptの Date への変換が大変であるため string で持つ仕様になっているようです。したがって、date なカラムのTypeScriptでの型は直感的には Date ですが、実際には string が正しいようです。

詳細

以下のEntityを例とします。

@Entity('users')
export class User extends AbstractEntity {
  @Column('varchar', {
    name: 'name',
  })
  public name!: string;

  @Column('date', {
    name: 'birthday',
    nullable: true,
  })
  public birthday!: Date; // <- 正しくは `string`
}
Enter fullscreen mode Exit fullscreen mode

ここで、カラム birthdayDate とされていますが、これは不適切で string であるべきです。なぜならTypeORMの内部では、日付情報を決まったフォーマットの文字列、すなわち string 型の値で持つ仕様になっているためです。

TypeORMのCore Comitterである@pleerock氏は、この挙動について次のように言及しています。

date is mapped into string since it causes lot of issues when its mapped into Date because of missing hours minutes and seconds. Only full datetime is mapped into Date object. We had lot of discussions about dates behaviour in past
Date column returns a date string instead of a date object · Issue #2176 · typeorm/typeorm

「時刻情報を含まない date なカラムの値をJSの Date に変換する際、秒・分・時の情報が無いが故に様々な問題を引き起こすため変換せず文字列で持っている」とのことです。

というわけで date なカラムの値を文字列で受け取ることになるわけですが、 逆にデータを格納する際の便利のため、 Date から string (各DBMSごとのdate-stringのフォーマットに則った文字列(例えばMySQLなら YYYY-MM-DD もしくは YYYYMMDD )に変換する関数を用意しておくと良いです。

import { format } from 'date-fns';

function convertDateObjectToDateString(date: Date) {
    return format(date, 'YYYYMMDD');
}
Enter fullscreen mode Exit fullscreen mode

string でもらった date なカラムの値を自力で Date にしたいという人は、まあ頑張ってください。

おしまい

Top comments (0)