@typescript-eslint/no-empty-object-type
Disallow the {} type and empty interfaces
Also called typescript-eslint/no-empty-object-type, typescript/no-empty-object-type
{} doesn't mean "an object with no properties". It accepts every value except null and undefined, so 0, "" and [] all pass. An interface with no members behaves the same way. Use object for "any object", unknown for "any value", and Record<string, never> for an object that has no properties.
An empty interface that extends one other type is reported too, because it's only a second name for that type.
{} in an intersection, such as T & {}, isn't reported. There it's a way to remove null and undefined from T.
This rule is on by default in TypeScript files.
Configure#
On by default as a warning. To turn it off:
[lint.rules]
"@typescript-eslint/no-empty-object-type" = "off" # or "error"Every option, set to its default. The ones that are commented out are unset by default.
[lint.rules]
"@typescript-eslint/no-empty-object-type" = ["warn", {
allowInterfaces = "never", # "always", "never" or "with-single-extends"
allowObjectTypes = "never", # "always" or "never"
# allowWithName = <string>,
}]Examples#
let settings: {}The {} ("empty object") type allows any non-nullish value, including literals like 0 and "".If that's what you want, disable this lint rule with an inline comment or configure the allowObjectTypes rule option.If you want a type meaning "any object", you probably want object instead.If you want a type meaning "any value", you probably want unknown instead. = 42; // no type error
interface PropsAn empty interface declaration allows any non-nullish value, including literals like 0 and "".If that's what you want, disable this lint rule with an inline comment or configure the allowInterfaces rule option.If you want a type meaning "any object", you probably want object instead.If you want a type meaning "any value", you probably want unknown instead. {}let settings: object = { theme: "dark" };
let payload: unknown = 42;
let nothing: Record<string, never> = {};
type Defined<T> = T & {};Options#
| Option | Default | What it does |
|---|---|---|
allowInterfaces | "never" | "always" allows every empty interface. "with-single-extends" allows one that extends one type. |
allowObjectTypes | "never" | "always" allows the {} type. |
allowWithName | none | A regular expression. An empty interface, or a type alias for {}, is allowed if its name matches. |
{ "allowInterfaces": "with-single-extends" }No problemsinterface User {
name: string;
}
interface Admin extends User {}With allowWithName, you can allow a component's empty props and nothing else:
{ "allowWithName": "Props$" }No problemsinterface HeaderProps {}
type FooterProps = {};{ "allowWithName": "Props$" }1 probleminterface HeaderStateAn empty interface declaration allows any non-nullish value, including literals like 0 and "".If that's what you want, disable this lint rule with an inline comment or configure the allowInterfaces rule option.If you want a type meaning "any object", you probably want object instead.If you want a type meaning "any value", you probably want unknown instead. {}