Closed2

[TypeScript] object の union で Omit すると union じゃなくなる問題

nbstshnbstsh

状況

以下のような Action union が存在するとして、

type TextAction = {
  type: 'text';
  text: string;
  label: string;
};

type UrlAction = {
  type: 'url';
  url: string;
  label: string;
};

type Action = TextAction | UrlAction;

label を取り除いた以下の Expected のような union を作りたいとして、

type Expected = {
  type: 'text';
  text: string;
} | {
  type: 'url';
  url: string;
}

Omit<> すればいけそうだが、思ったようにならない

type ActionWithoutLabel = Omit<Action, 'label'>;

nbstshnbstsh

解決方法: Union Distribution を使う

Conditional type に union を渡すと、各要素に対して 型の判定が行われる。

type WithoutLabel<T> = T extends Action ? Omit<T, 'label'> : T;
type ActionWithoutLabel = WithoutLabel<Action>;

WithoutLabel<Action> は以下のような型となる↓

type ActionWithoutLabel = Omit<TextAction, "label"> | Omit<UrlAction, "label">
このスクラップは2024/08/15にクローズされました