Introduction
Builded Omit
type can be very useful
e.g.:
interface Obj {
key1: string;
key2: number;
}
type R1 = Omit<Obj, 'key1'>; // { key2: number }
type R2 = Omit<Obj, 'key2'>; // { key1: string }
However there's one disadvantage.
interface Obj {
key1: string;
key2: number;
}
type R1 = Omit<Obj, 'kye1'>; // { key1: string; key2: number }
Omitting a key that doesn't exist is pointless, so I'll expect some error.
Implementation
Omit type looks like this:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Problem is that K is not key of anything, it's a key of this object. So let's change it:
// type.utils.ts
export type Omit2<T extends {}, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
interface Obj {
key1: string;
key2: number;
}
type R1 = Omit2<Obj, 'kye1'>; // Type '"kye1"' does not satisfy the constraint 'keyof Obj'.(2344)
Installation
Now we have to ensure that Omit2 will be used instead of Omit. I've no idea how to overwrite something from es5.d.ts
, however we can ban Omit
using eslint.
// eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
"@typescript-eslint/ban-types": [
"error",
{
"types": {
"Omit": "Use Omit2 from type.utils instead",
},
"extendDefaults": true
}
]
}
Then if someone forgot about the presence of Omit2
eslint will throw an error with a proper message.
Summary
It's not a big improvement but maybe it will catch a bug or two.
Read more
Checkout discussion about strict-ness of Omit. https://github.com/microsoft/TypeScript/issues/30825
Or just don't use Omit dev.to/skyjur/your-code-probably-d...