Home > Enterprise >  Why does `Omit<undefined, 'foo'>` seem to produce `any`?
Why does `Omit<undefined, 'foo'>` seem to produce `any`?

Time:09-26

It seems like I can assign whatever I want to this type, without errors - it's effectively any. Why is that?

type OmittedUndefined = Omit<undefined, 'foo'>;

let a: OmittedUndefined = 1234;
a = "asdflkjasdf";
a = { hello: 1234 };

playground

CodePudding user response:

You need to look at definition of Omit:

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}

This allows us to reduce your type Omit<undefined, 'foo'> as follows:

Omit<undefined, 'foo'> =
Pick<undefined, Exclude<keyof undefined, 'foo'>> =
Pick<undefined, never> =
{
    [P in never]: undefined[P];
} =
{}

We concluded that type Omit<undefined, 'foo'> is equivalent to an empty interface.

Note that normally you cannot directly assign an object literal to a type when the object literal contains more properties than are specified in the type. But in the case of an empty interface, this check is not done, and such assignments will be successful.

This special behaviour of empty interfaces might be confusing, which is the reason empty interfaces are flagged by static analysis tools.

See https://rules.sonarsource.com/typescript/RSPEC-4023

  • Related