no-empty-object-type
Disallow accidentally using the "empty object" type.
在 ESLint 配置 中扩展"plugin:@typescript-eslint/recommended"
可启用此规则。
此规则报告的一些问题可以通过编辑器 建议 手动修复。
TypeScript 中的 {}
或 "空对象" 类型是让不熟悉 TypeScript 结构类型的开发者感到困惑的常见原因。{}
表示任何非空值,包括像 0
和 ""
这样的文字:
¥The {}
, or "empty object" type in TypeScript is a common source of confusion for developers unfamiliar with TypeScript's structural typing.
{}
represents any non-nullish value, including literals like 0
and ""
:
let anyNonNullishValue: {} = 'Intentionally allowed by TypeScript.';
通常,开发者编写 {}
的意思是:
¥Often, developers writing {}
actually mean either:
-
object
:表示任何对象值¥
object
: representing any object value -
unknown
:表示任何值,包括null
和undefined
¥
unknown
: representing any value at all, includingnull
andundefined
换句话说,"空对象" 类型 {}
实际上是 "任何已定义的值"。这包括数组、类实例、函数和原语,例如 string
和 symbol
。
¥In other words, the "empty object" type {}
really means "any value that is defined".
That includes arrays, class instances, functions, and primitives such as string
and symbol
.
为了避免混淆 {}
类型允许任何非空值,此规则禁止使用 {}
类型。这包括没有字段的接口和对象类型别名。
¥To avoid confusion around the {}
type allowing any non-nullish value, this rule bans usage of the {}
type.
That includes interfaces and object type aliases with no fields.
如果你确实有一个允许 {}
的 API 用例,你始终可以配置 规则的选项、使用 ESLint 禁用注释 或 在你 的 ESLint 配置。
¥If you do have a use case for an API allowing {}
, you can always configure the rule's options, use an ESLint disable comment, or disable the rule in your ESLint config.
请注意,此规则不报告:
¥Note that this rule does not report on:
-
{}
作为交叉类型中的类型组成部分(例如,TypeScript 内置的type NonNullable<T> = T & {}
之类的类型),因为这在类型系统操作中很有用。¥
{}
as a type constituent in an intersection type (e.g. types like TypeScript's built-intype NonNullable<T> = T & {}
), as this can be useful in type system operations. -
从多个其他接口扩展的接口。
¥Interfaces that extend from multiple other interfaces.
- Flat Config
- Legacy Config
export default tseslint.config({
rules: {
"@typescript-eslint/no-empty-object-type": "error"
}
});
module.exports = {
"rules": {
"@typescript-eslint/no-empty-object-type": "error"
}
};
在线运行试试这个规则 ↗
示例
¥Examples
- ❌ Incorrect
- ✅ Correct
let anyObject: {};
let anyValue: {};
interface AnyObjectA {}
interface AnyValueA {}
type AnyObjectB = {};
type AnyValueB = {};
Open in Playgroundlet anyObject: object;
let anyValue: unknown;
type AnyObjectA = object;
type AnyValueA = unknown;
type AnyObjectB = object;
type AnyValueB = unknown;
let objectWith: { property: boolean };
interface InterfaceWith {
property: boolean;
}
type TypeWith = { property: boolean };
Open in Playground选项
该规则接受以下选项:
type Options = [
{
/** Whether to allow empty interfaces. */
allowInterfaces?:
| 'never'
| 'with-single-extends'
/** Whether to allow empty interfaces. */
| 'always';
/** Whether to allow empty object type literals. */
allowObjectTypes?:
| 'never'
/** Whether to allow empty object type literals. */
| 'always';
/** A stringified regular expression to allow interfaces and object type aliases with the configured name. */
allowWithName?: string;
},
];
const defaultOptions: Options = [
{ allowInterfaces: 'never', allowObjectTypes: 'never' },
];
¥Options
默认情况下,此规则标记接口和对象类型。
¥By default, this rule flags both interfaces and object types.
allowInterfaces
Whether to allow empty interfaces. Default: "never"
.
允许的值为:
¥Allowed values are:
-
'always'
:始终允许没有字段的接口¥
'always'
: to always allow interfaces with no fields -
'never'
(默认):绝不允许没有字段的接口¥
'never'
(default): to never allow interfaces with no fields -
'with-single-extends'
:允许从单个基本接口extend
的空接口¥
'with-single-extends'
: to allow empty interfaces thatextend
from a single base interface
带有 { allowInterfaces: 'with-single-extends' }
的此规则的正确代码示例:
¥Examples of correct code for this rule with { allowInterfaces: 'with-single-extends' }
:
interface Base {
value: boolean;
}
interface Derived extends Base {}
Open in PlaygroundallowObjectTypes
Whether to allow empty object type literals. Default: "never"
.
允许的值为:
¥Allowed values are:
-
'always'
:始终允许没有字段的对象类型文字¥
'always'
: to always allow object type literals with no fields -
'never'
(默认):绝不允许没有字段的对象类型文字¥
'never'
(default): to never allow object type literals with no fields
allowWithName
A stringified regular expression to allow interfaces and object type aliases with the configured name.
如果你现有的代码样式包括使用 {}
而不是 object
声明空类型的模式,这可能很有用。
¥This can be useful if your existing code style includes a pattern of declaring empty types with {}
instead of object
.
带有 { allowWithName: 'Props$' }
的此规则的代码示例:
¥Examples of code for this rule with { allowWithName: 'Props$' }
:
- ❌ Incorrect
- ✅ Correct
interface InterfaceValue {}
type TypeValue = {};
Open in Playgroundinterface InterfaceProps {}
type TypeProps = {};
Open in Playground何时不使用它
¥When Not To Use It
如果你的代码通常需要表示 "任何非空值" 类型,则此规则可能不适合你。广泛使用类型操作(例如条件类型和映射类型)的项目通常会受益于禁用此规则。
¥If your code commonly needs to represent the "any non-nullish value" type, this rule may not be for you. Projects that extensively use type operations such as conditional types and mapped types oftentimes benefit from disabling this rule.
进一步阅读
¥Further Reading
-
增强功能:[ban-types] 将 禁令拆分为单独的、措辞更好的规则
¥Enhancement: [ban-types] Split the ban into a separate, better-phrased rule
'## 资源'