以前にEnumのようなUnion型を生成する方法を調べた
このとき、Keyの型チェックに対しては$Keys
を使うことがわかったが、Valueに対しての型チェックはどうやるのかがわからなかったので調べたら、単純に$Values
を使えばよいだけではなかったので別でまとめることにした
やり方はこちらの記事が参考になった
下のような定数オブジェクトに対して、
const statuses = { APPROVED: 'approved', REJECTED: 'rejected', PENDING: 'pending' };
こういう型を作りたいが、
type Status = 'approved' | 'rejected' | 'pending';
ハードコーディングしていると変更が大変なのでうまくやりたい
冒頭でいったように$Values
を使えばよいかと考えたが、うまく型チェックされない
const statuses = { APPROVED: 'approved', REJECTED: 'rejected', PENDING: 'pending' }; type Status = $Values<typeof statuses>; const status1: Status = "approved"; // Work! const status2: Status = "nope"; // Work!?
理由として、
Flowの中でプロパティをもったオブジェクトを生成すると、それをsealed object
として扱うため
つまり、プロパティの変更が可能である限り、型の推測はできるが値は推測できない
sealed object
とは新しいキーを追加することができないオブジェクト。ただし、既存の値を変更することはできる。
なので、次のようにオブジェクトをfreeze
させるとよいとのこと
const statuses = Object.freeze({ APPROVED: 'approved', REJECTED: 'rejected', PENDING: 'pending' });
ただし、このfreezeオブジェクトとtypeが別ファイルだと機能しなくなるので同じファイルに置く必要がある