31
4

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 5 years have passed since last update.

Omitで複数のプロパティを同時に除外する

Posted at

TypescriptのOmitで複数のプロパティを除外する時に、

Omit<Omit<HOGE,"fuga">,"piyo">

というような恰好悪いことをやっていたのですが、
全然意味を理解していなかったことを痛感したので備忘を兼ねて

正しいやり方

Omit<HOGE,"fuga" | "piyo">

複数のフィールドを除外したい場合は、それらのプロパティ名をUnion型で渡してやればOK。

原理

Omitの定義をたどると、

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

となります。

この時重要なのがkeyofで、これは後に続く型のプロパティ名をUnion型で返します。
Omitの場合anyなのでstringがnumberかsymbolで構成されたUnion型ならOKです。
このため、上記の正しいやり方で示した "fuga"|"piyo"のように複数のプロパティ名をを渡すことが可能です。

Kがどう扱われるのか

その後の定義を見ていくと、Exclude<keyof T,K>しています。
ここでT全体のpropertyを列挙したUNION型からKで指定したものを抜くわけです。
さらに、得られた残りのプロパティ名の集合(UNION型)をPickに渡しています。
Pickも似たような形で、 K extends keyof Tという形で第二型引数を受けているので、UNION型を渡せます。

Pickの中身

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

Pickの定義は上記の通り。
Kに含まれるプロパティPの方はTにPでアクセスしたときのものと同じという意味。
仕組み的には以下と同じ。

type HOGE = {
    [fuga:number]:string
}
type s = HOGE[number]//s はstring

このような型定義をしているため、PickのKは extends keyof Tでなければならないわけですね。

まとめ

  • OmitやPickに複数指定したい時はUnion型で渡す
  • keyofはプロパティをUnion型で返す
31
4
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
31
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?