A stricter Omit type

TypeScript provides globally available utility types that are useful when manipulating and transforming types. One of the types, Omit can be used to define a new type with specific properties removed from an existing type. It works like this:

type Song = {
  album: string
  artist: string
  title: string
  loved: boolean
}

type X = Omit<Song, "title" | "loved">
//
// {
//   album: string
//   artist: string
// }

A thing I’ve disliked about the built-in Omit type is that providing a non-existent property to Omit doesn’t result in a compile-time error.

As an example, if we renamed the title property to name in the Song type, the code still compiles successfully.

type Song = {
  album: string
  artist: string
  name: string // renamed
  loved: boolean
}

type X = Omit<Song, "title" | "loved"> 
// compiles successfully though `title` doesn't exist on SongProps
//
// {
//   album: string
//   artist: string
//   name: string
// }

Here’s the stricter version of Omit, called OmitStrict, that I defined at work in our typeutil package, as a drop-in replacement for Omit:

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

Compare this to the original Omit:

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

Using keyof T instead of any ensures that the specified property is actually present on the type T which you’re omitting the property from.

 
5
Kudos
 
5
Kudos

Now read this

Properly typed omit function in TypeScript

Writing a properly typed omit function requires a few type casts. I think this is the cleanest possible way (I’d be thrilled to learn of a cleaner way), and it doesn’t include an allocation for an Object.keys(obj) array. function... Continue →