7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TypeORMのsimple-arrayでnumber配列を扱う | Use number array as actual value of TypeORM's "simple-array" typed entity columns

Last updated at Posted at 2020-03-04

TypeORMはTypeScriptで使えるORM。

すごくニッチなニーズな気もするが、simple-arrayというTypeORM特有の型をコード中で扱う際に、numberの配列として扱いたい。

simple-array

doc

配列をDBに手軽にストアしたいなら便利。ただしDocに明記されていない問題が一つ。

string要素以外格納できない。

より厳密に言うと、string以外の要素を含んだ配列を渡すと、DBから値を取得する際にstringとして返ってくる。

ex) [1, 2, 3] -> DB -> ['1', '2', '3']


@Column({ type: 'simple-array' })
public elements: number[]

のように定義していても上記のような動作をするので、普通に嫌だ

https://github.com/typeorm/typeorm/issues/1092
https://github.com/typeorm/typeorm/issues/2267

この辺を見ても分かるが、TypeORM側としてはライブラリサポートする気はなさそう。

どうするか

これで解決できた。


@Column({ type: 'simple-array', nullable: true })
public elements: number[]

/**
 * @NOTE: simple-array type automatically save column as string.
 * numifyElements will fix string elements to number after each time entity is loaded.
*/
@AfterLoad()
numifyElements() {
  if (this.elements&& this.elements.length) {
    this.elements.forEach((e, i, self) => self[i] = parseInt(String(e), 10))
  }
}

@AfterLoadデコレータがついた関数を定義しておくと、Entityがロードされる度に所定の処理を行うことができる。
simple-arrayは少なくとも配列の状態でロードしてくれるので、その要素を自分が求める型に変換する。

カラム定義はnumber[]にしておかないとコード内で型について怒られる。
ただし、そうすることによってnumifyElements内のparseInt(String(id), 10)でわざわざidをStringで囲う必要が出てくる。

なぜなら既にnumberと定義されているものをparseIntに渡すので、tsに怒られてしまうから。

そもそもnumber[]と定義しているにも関わらず、なぜstring[]を入れることができているのかについてはよくわからない。

そのうちちゃんと調べよう。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?