Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript Omit does not show error when using reference

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

interface objInterface {
  first: string;
  second: string;
}

const obj = {
  first: "first",
  second: "second"
};

const out: Omit<objInterface, "first"> = obj;

I was expecting this to have some intellisense errors, but it does not. This however does show some errors, anyone know why?

const out: Omit<objInterface, "first"> = {
  first: 'first',
  second: 'second'
};
like image 733
seasick Avatar asked Jun 06 '26 00:06

seasick


2 Answers

In addition to @kingdaro's correct point about excess property checks on object literals,

The definition of Omit<T,K> just widens the type of T so that it does not contain a known property at K ("I don't know or care if K is a property; I will ignore it."), which is not the same as prohibiting a property at K. That is, T is a subtype of Omit<T, K>, and any value of type T will be also be assignable to type Omit<T, K>. If your intent is to actually prohibit a property at K, you can (kind of) do this by specifying that the K property is optional and has a value type of never (or undefined, see below). Let's call that ForcefullyOmit<T, K>:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type ForcefullyOmit<T, K extends keyof T> = Omit<T, K> & Partial<Record<K, never>>; 

And let's see if it works:

interface ObjInterface {
  first: string;
  second: string;
}

const obj = {
  first: "first",
  second: "second"
};

const out: ForcefullyOmit<ObjInterface, "first"> = obj; // error
// types of property "first" are incompatible
// string is not assignable to undefined

Looks good.

It's only "kind of" prohibiting the key, since it will still allow a property at that key of type undefined (or never), but that's kind of an unresolved issue in TypeScript... the language doesn't always distinguish between missing properties and undefined ones.

It's up to you if your use case really needs the stricter behavior of ForcefullyOmit. Anyway, hope that helps; good luck!

like image 167
jcalz Avatar answered Jun 07 '26 13:06

jcalz


TS only errors on excess properties when defining the object as a literal, by design. https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks

like image 25
kingdaro Avatar answered Jun 07 '26 13:06

kingdaro