seasick
seasick

Reputation: 1225

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'
};

Upvotes: 1

Views: 4246

Answers (2)

jcalz
jcalz

Reputation: 328503

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!

Upvotes: 8

kingdaro
kingdaro

Reputation: 12018

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

Upvotes: 3

Related Questions