Skip to main content

no-generated-empty-object-type

Disallow type operations that resolve to the "empty object" type.

💭

This rule requires type information to run, which comes with performance tradeoffs.

The {}, or "empty object" type, allows any value except null and undefined. It is rarely what you want it to be: even primitives such as 0 and "" are assignable to it.

no-empty-object-type reports {} written out by hand. This rule instead reports type operations that resolve to {}, which is usually a sign that the operation went wrong. For example, Omit<T, K> distributes over a union, so Omit<null | { a: number; b: string }, 'a'> resolves to {} rather than null | { b: string }.

eslint.config.mjs
export default defineConfig({
rules: {
"@typescript-eslint/no-generated-empty-object-type": "error"
}
});

Try this rule in the playground ↗

Examples

type Data = { name: string; value: number };
type NullableData = null | Data;

// `Omit<null>` becomes {}, so this is `{} | { value: number }`, or `{}`
type Unexpected = Omit<NullableData, 'name'>;
Open in Playground

Options

This rule is not configurable.

When Not To Use It

If you intentionally rely on type operations producing {}, such as to describe "any non-nullish value" for non-trivial type logic, this rule may not be for you. Note that NonNullable<unknown> is a more explicit way to write that type, and is still reported by this rule.


Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.

See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.

Resources