Typescript: Add `Omit` as a known interface

Created on 18 Mar 2019  ·  14Comments  ·  Source: microsoft/TypeScript

Search Terms

Omit

Suggestion

Add the following type to lib.d.ts:

type Omit<ObjectType, KeysType extends keyof ObjectType> = Pick<ObjectType, Exclude<keyof ObjectType, KeysType>>;

More

Origin : https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-420919470

From : https://github.com/sindresorhus/type-fest/blob/0226ef2092ee2b07a8714c832d106da659877a8f/index.d.ts#L75 Please open new issues on TypeScript about making it built-in.. I searched but couldn't find an issue, so here it is :rose:

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.
Breaking Change Committed Fixed In Discussion Suggestion

Most helpful comment

@nmain My 2¢, trivial for some magic for others, I would argue all build-in mapped and conditional types are trivial to write but that does not make them any less useful. Having a common set of types makes code easier to understand across projects. Omit is also simpler to understand for newer typescript devs and they don't have to do conditional type math when looking at a definition, they just care about the behavior of the type.

All 14 comments

Duplicate of #19569?

Not really? That was back when there was only a hairy mapped-type based definition of Omit which we didn't particularly like, so didn't want to add.

Eventually that issue was closed after conditional types were added. @ahejlsberg made https://github.com/Microsoft/TypeScript/pull/21847 and said:

We did not include the Omit<T, K> type because it is trivially written as Pick<T, Exclude<keyof T, K>>

@nmain My 2¢, trivial for some magic for others, I would argue all build-in mapped and conditional types are trivial to write but that does not make them any less useful. Having a common set of types makes code easier to understand across projects. Omit is also simpler to understand for newer typescript devs and they don't have to do conditional type math when looking at a definition, they just care about the behavior of the type.

I personally use Omit much more often than the other built-in helper types.

Totally agree, I end up declaring that Omit type in almost every project.
It's like Record<string, string> could be written { [k: string]: string}. I prefer the Record helper, same feeling about this one.

I've used Omit in every single project and every single time I have to look it up, because Pick<T, Exclude<keyof T, K>> isn't trivial to recall; if many people use it in every project, it make sense to make it part of lib.d.ts right?

It's like Record could be written { [k: string]: string}. I prefer the Record helper, same feeling about this one.

That's not the same; and it's not even close.

That's not the same; and it's not even close.

How so? Isn't it better to explain your train of thought when you say someone's wrong?...

That's not the same; and it's not even close.

How so? Isn't it better to explain your train of thought when you say someone's wrong?...

Sorry, you're right -- and my thoughts were wrong anyway. I would even say that omit is far more difficult than record!

What I should have said is that it's better to compare Record<keyof K, string> to { [P in K]: string }.

The docs' reasoning about this is:

We did not include the Omit type because it is trivially written as Pick>

I'm not so sure about the triviality of it, especially for new TS devs, but IMHO this isn't a good reason for not including Omit, to me it feels like saying that if I have this code:

return collection.map ( item => item.foo () );

I don't really need map because it's trivial to do the same with forEach:

const result = [];
collection.forEach ( item => result.push ( item.foo () ) );
return result;

I mean yeah, it's trivial, but am I supposed to write such ugly code every time or am I supposed to redefine map every time?

This is now 3.5-bound! :rocket:

You can try it out with our next nightly release.

For those curious how the Omit type is used, you can find that information here.

The naming of this is rather unfortunate. I mean to say, what exactly is the difference between the words "Omit" and "Exclude"? They are essentially synonyms with a minor nuance.

The definition we have used is ExcludeProperty.

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T;

/**
 * From T remove the properties K
 * E.g. ExcludeProperty<{ a: number, b: string }, 'b'> => { a: number }
 */
type ExcludeProperty<T, K extends keyof T> = Pick<T, Exclude<StringKeyOf<T>, K>>;

For everyone watching this issue, note that the Omit type that was added is not the strict one suggested here. See: https://github.com/Microsoft/TypeScript/issues/30825.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dlaberge picture dlaberge  ·  3Comments

wmaurer picture wmaurer  ·  3Comments

blendsdk picture blendsdk  ·  3Comments

DanielRosenwasser picture DanielRosenwasser  ·  3Comments

fwanicka picture fwanicka  ·  3Comments