レガシーから新しいパターンへ移行
Object.freeze
などの JavaScript の古い Enum パターンからどのように Flow Enumに移行するかについて学習します。
まず、Enum の定義サイトをアップデートする方法を学び、次に Enum をインポートして使用しているファイルをアップデートする方法を学びます。
定義のアップデート
Object.freeze
Object.freeze
を使用している場合、オブジェクトの値が次のとおりであれば、そのオブジェクトを Enum に移行できます。
- 同じ基本型であり、その型が
boolean
、string
、number
、symbol
である。 - すべてリテラルである。
- 重複する値を含まない。
次のコードを置き換えます。
1const Status = Object.freeze({2 Active: 1,3 Paused: 2,4 Off: 3,5});6
7export type StatusType = $Values<typeof Status>;8
9export default Status;
次のコードに置き換えます。
1export default enum Status {2 Active = 1,3 Paused = 2,4 Off = 3,5}
- キー名が小文字の 'a' から 'z' で始まっていないことを確認します(Enum では許可されていません)。始まっている場合は、メンバー名を変更する必要があります。
- Enum 型での
$Keys<...>
または$Values<...>
の使用を削除します。これらは不要になりました。Flow Enum はそれ自体が型(その名前)を定義するためです。 - Enum に基づいた型のエクスポートをすべて削除します。Flow Enum をエクスポートする必要があるだけです。Flow Enum は型と値の両方として機能します(クラスのように)。
次に、Enum をインポートして使用するファイルをアップデートする方法を確認します。
keyMirror
keyMirror
ユーティリティは、キー名をミラーする値を持つオブジェクトを作成します。keyMirror
の使用を文字列ベースの Enum に置き換えることができます。
次のコードを置き換えます。
import keyMirror from 'keyMirror';
const Status = keyMirror({
Active: null,
Paused: null,
Off: null,
});
export type StatusType = $Keys<typeof Status>;
export default Status;
次のコードに置き換えます。
1export default enum Status {2 Active,3 Paused,4 Off,5}
- キー名が小文字の 'a' から 'z' で始まっていないことを確認します(Enum では許可されていません)。始まっている場合は、メンバー名を変更する必要があります。
- Enum 型での
$Keys<...>
の使用をすべて削除します。これらは不要になりました。Flow Enum はそれ自体が型(その名前)を定義するためです。 - Enum に基づいた型のエクスポートをすべて削除します。Flow Enum をエクスポートする必要があるだけです。Flow Enum は型と値の両方として機能します(クラスのように)。
次に、Enum をインポートして使用するファイルをアップデートする方法を確認します。
使用のアップデート
型のインポートの修正
以前のパターンでは、Enum 自体とは別に型をエクスポート(してからインポート)する必要がありました。Flow Enum は型と値の両方です(クラスのように)。つまり、Flow Enum自体をエクスポートするだけで済みます。エクスポートが 1 つになったので、インポートも 1 つで済みます。Enum のエクスポートとEnum のインポートについてさらに詳しく読む。
以前に次のようにしていた場合
1const Status = Object.freeze({2 Active: 1,3 Paused: 2,4 Off: 3,5});6export type StatusType = $Values<typeof Status>;7export default Status;
そして置き換え
1export default enum Status {2 Active = 1,3 Paused = 2,4 Off = 3,5}
インポートも修正する必要がある
型と値の両方をインポートした場合
以前に enum の型と値の両方をインポートしている、enum のユーザーの場合は、型インポートを削除し、使用されているアノテーションを更新できます。
変更
import type {StatusType} from 'status';
import Status from 'status';
const myStatus: StatusType = Status.Active;
宛先
// Type import is deleted
import Status from 'status';
const myStatus: Status = Status.Active; // Changed type annotation to just `Status`
型のみをインポートした場合
以前に単に enum の型のみをインポートしている enum のユーザーの場合は、型インポートの名前付きインポートではなくデフォルトインポートに変更します。
変更
import type {StatusType} from 'status';
function isActive(status: StatusType) { ... }
宛先
// Remove the braces `{` `}` and changed the name - this is a default import now
import type Status from 'status';
function isActive(status: Status) { ... } // Changed type annotation to just `Status`
enum を他の値にマッピング
場合によっては、enum の値を他の値にマッピングしたいことがあります。これまで私たちは、そのためにオブジェクトリテラルを使用することが時々ありました。Flow Enum では、代わりに switch
で関数を使いましょう。この switch は徹底的にチェックされるので、Flow Enum のメンバーを追加、削除した時に、マッピングを更新するように Flow が確実に行います。
このパターンで置き換え
const STATUS_ICON: {[Status]: string} = {
[Status.Active]: 'green-checkmark',
[Status.Paused]: 'grey-pause',
[Status.Off]: 'red-x',
};
const icon = STATUS_ICON[status];
次のコードに置き換えます。
function statusIcon(status: Status): string {
switch (status) {
case Status.Active:
return 'green-checkmark';
case Status.Paused:
return 'grey-pause';
case Status.Off:
return 'red-x';
}
}
const icon = statusIcon(status);
enum を他の値にマッピングの詳細については、こちらをご覧ください。
リプリゼンテーション型(例:文字列)として使用
Flow Enum をリプリゼンテーション型(例:string
)として直接使用することはできません。Flow Enum をリプリゼンテーション型として使用すると、Flow エラーが返されたら、まず、リプリゼンテーション型ではなく enum 型を必要とするようにコードをリファクタリングしてみてください(例:string
から Status
のアノテーションへ変更します)。enum を実際にリプリゼンテーション型として使用したい場合は、明示的なキャストを追加できます。詳細はリプリゼンテーション型へのキャストをご覧ください。
enum 型へのキャスト
これまで次のようなやり方で enum のリプリゼンテーション型(例:string
)から enum 型へキャストしていた場合
function castToStatus(input: number): StatusType | void {
switch(input) {
case 1: return Status.Active;
case 2: return Status.Paused;
case 3: return Status.Off;
default: return undefined;
}
}
castToStatus(x);
今では、キャストメソッドを使用できます。
Status.cast(x);
スイッチ文のアップデート
Flow Enum は、switch
文で徹底的にチェックされます。enum 値で切り替えると、コードをアップデートする必要があるかもしれません。switch 文で enum を徹底的にチェックするの詳細をご覧ください。
enum メンバーに対する操作
enum メンバーを取得、操作するために Object.values
、Object.keys
、 for-in
ループなどの機能をこれまで使用していた場合は、代わりにメンバーメソッドを使用できます。