はじめに
先日、CureAppで毎週行っている勉強会でTypeScriptのOmitの話になりました。
Pickはインテリセンス効くけど、Omitはインテリセンス効かないというものです。
TypeScriptとしてはこちらの議論の末、今のインテリセンスが効かない今の実装になっているようです。
インテリセンスが効くようにOmitをなんとか上書きできないかとちょくちょく調べていたのですが、
あまり良い方法が見つからず絶望したので、メモとして代替案を残しておこうと思います。
Omitの実装
まず、Omitの実装を確認してみます。
// lib.es5.d.ts
/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
個人的にkeyof any
を見て発狂しそうなのですが、Omitはtypeで宣言されているので上書きは出来ません。
なので、必然的に下記のどちらかの対応になりそうです。
- patch-packages等で、
lib.es5.d.ts
のOmitの実装を変更する - マイOmitを作る
patch-packages等で、lib.es5.d.ts
のOmitの実装を変更する
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
を
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
に変更します。
使用しているTypeScriptのバージョン変更時にはパッチの修正が必要になりますが、
後者よりは対応が小さく済みます。
マイOmitを作る
議論でもあがっていましたが、下記のような独自Omitを作る方法です。
type OmitScrict<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
Omitがあるのに、OmitStrict…(白目)
ちなみに、組み込みのOmitを使用しないことを強制する場合は、eslintにルールを追加します。
{
rules: {
'@typescript-eslint/ban-types': [
'error',
{
types: {
Omit: "Use `OmitStrict`.",
},
},
],
}
}
さいごに
下記のような実装で済むのが理想でしたが、あまり良い方法が見つけられませんでした。
declare type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
他にもっと良い方法があったら教えて頂けると幸いです。