no-type-alias
Disallow type aliases.
此规则已被弃用,以支持 @typescript-eslint/consistent-type-definitions
规则。TypeScript 类型别名是一项普遍必需的语言功能;完全禁止它往往会适得其反。
¥This rule has been deprecated in favour of the @typescript-eslint/consistent-type-definitions
rule.
TypeScript type aliases are a commonly necessary language feature; banning it altogether is oftentimes counterproductive.
如果你想要禁止某些分类的类型别名,请考虑使用 no-restricted-syntax
。参见 故障排除和常见问题解答。
¥If you want to ban certain classifications of type aliases, consider using no-restricted-syntax
.
See Troubleshooting & FAQs.
在 TypeScript 中,类型别名有三个用途:
¥In TypeScript, type aliases serve three purposes:
-
给其他类型起别名,以便我们可以使用更简单的名称来引用它们。
¥Aliasing other types so that we can refer to them using a simpler name.
// this...
type Person = {
firstName: string;
lastName: string;
age: number;
};
function addPerson(person: Person) {
// ...
}
// is easier to read than this...
function addPerson(person: {
firstName: string;
lastName: string;
age: number;
}) {
// ...
}
-
其行为有点像接口,提供一组必须存在于实现该类型的对象中的方法和属性。
¥Act sort of like an interface, providing a set of methods and properties that must exist in the objects implementing the type.
type Person = {
firstName: string;
lastName: string;
age: number;
walk: () => void;
talk: () => void;
};
// you know person will have 3 properties and 2 methods,
// because the structure has already been defined.
var person: Person = {
// ...
};
// so we can be sure that this will work
person.walk();
-
就像类型之间的映射工具一样,允许快速修改。
¥Act like mapping tools between types to allow quick modifications.
type Immutable<T> = { readonly [P in keyof T]: T[P] };
type Person = {
name: string;
age: number;
};
type ImmutablePerson = Immutable<Person>;
var person: ImmutablePerson = { name: 'John', age: 30 };
person.name = 'Brad'; // error, readonly property
当使用别名时,类型别名不会创建新类型,它只是创建一个新名称来引用原始类型。因此,对基元和其他简单类型、元组、并集或交集进行别名有时可能是多余的。
¥When aliasing, the type alias does not create a new type, it just creates a new name to refer to the original type. So aliasing primitives and other simple types, tuples, unions or intersections can some times be redundant.
// this doesn't make much sense
type myString = string;
另一方面,使用类型别名作为接口可能会限制你执行以下操作的能力:
¥On the other hand, using a type alias as an interface can limit your ability to:
-
重用你的代码:接口可以通过其他类型扩展或实现。类型别名不能。
¥Reuse your code: interfaces can be extended or implemented by other types. Type aliases cannot.
-
调试你的代码:接口创建一个新名称,因此在调试应用时很容易识别对象的基本类型。
¥Debug your code: interfaces create a new name, so is easy to identify the base type of an object while debugging the application.
最后,映射类型是一种高级技术,将其保持开放状态很快就会成为应用的痛点。
¥Finally, mapping types is an advanced technique and leaving it open can quickly become a pain point in your application.
- Flat Config
- Legacy Config
export default tseslint.config({
rules: {
"@typescript-eslint/no-type-alias": "error"
}
});
module.exports = {
"rules": {
"@typescript-eslint/no-type-alias": "error"
}
};
在线运行试试这个规则 ↗
示例
¥Examples
该规则不允许使用类型别名,而是使用接口和简化类型(基元、元组、并集、交集等)。
¥This rule disallows the use of type aliases in favor of interfaces and simplified types (primitives, tuples, unions, intersections, etc).
选项
该规则接受以下选项:
type ExpandedOptions =
| 'always'
| 'in-intersections'
| 'in-unions'
| 'in-unions-and-intersections'
| 'never';
type SimpleOptions = 'always' | 'never';
type Options = [
{
/** Whether to allow direct one-to-one type aliases. */
allowAliases?: ExpandedOptions;
/** Whether to allow type aliases for callbacks. */
allowCallbacks?: SimpleOptions;
/** Whether to allow type aliases for conditional types. */
allowConditionalTypes?: SimpleOptions;
/** Whether to allow type aliases with constructors. */
allowConstructors?: SimpleOptions;
/** Whether to allow type aliases with generic types. */
allowGenerics?: SimpleOptions;
/** Whether to allow type aliases with object literal types. */
allowLiterals?: ExpandedOptions;
/** Whether to allow type aliases with mapped types. */
allowMappedTypes?: ExpandedOptions;
/** Whether to allow type aliases with tuple types. */
allowTupleTypes?: ExpandedOptions;
},
];
const defaultOptions: Options = [
{
allowAliases: 'never',
allowCallbacks: 'never',
allowConditionalTypes: 'never',
allowConstructors: 'never',
allowGenerics: 'never',
allowLiterals: 'never',
allowMappedTypes: 'never',
allowTupleTypes: 'never',
},
];
¥Options
allowAliases
Whether to allow direct one-to-one type aliases. Default: "never"
.
该设置接受以下值:
¥The setting accepts the following values:
-
"always"
或"never"
用于激活或停用该功能。¥
"always"
or"never"
to active or deactivate the feature. -
"in-unions"
,允许在联合语句中使用别名,例如type Foo = string | string[];
¥
"in-unions"
, allows aliasing in union statements, e.g.type Foo = string | string[];
-
"in-intersections"
,允许在交集语句中使用别名,例如type Foo = string & string[];
¥
"in-intersections"
, allows aliasing in intersection statements, e.g.type Foo = string & string[];
-
"in-unions-and-intersections"
,允许在联合和/或交集语句中使用别名。¥
"in-unions-and-intersections"
, allows aliasing in union and/or intersection statements.
{ "allowAliases": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowAliases": "always" }
options:
// primitives
type Foo = 'a';
type Foo = 'a' | 'b';
type Foo = string;
type Foo = string | string[];
type Foo = string & string[];
type Foo = `foo-${number}`;
// reference types
interface Bar {}
class Baz implements Bar {}
type Foo = Bar;
type Foo = Bar | Baz;
type Foo = Bar & Baz;
Open in Playground{ "allowAliases": "in-unions" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowAliases": "in-unions" }
option:
// primitives
type Foo = 'a';
type Foo = string;
type Foo = string & string[];
type Foo = `foo-${number}`;
// reference types
interface Bar {}
class Baz implements Bar {}
type Foo = Bar;
type Foo = Bar & Baz;
Open in Playground{ "allowAliases": "in-unions" }
选项的正确代码示例:
¥Examples of correct code for the { "allowAliases": "in-unions" }
option:
// primitives
type Foo = 'a' | 'b';
type Foo = string | string[];
type Foo = `a-${number}` | `b-${number}`;
// reference types
interface Bar {}
class Baz implements Bar {}
type Foo = Bar | Baz;
Open in Playground{ "allowAliases": "in-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowAliases": "in-intersections" }
option:
// primitives
type Foo = 'a';
type Foo = 'a' | 'b';
type Foo = string;
type Foo = string | string[];
type Foo = `a-${number}` | `b-${number}`;
// reference types
interface Bar {}
class Baz implements Bar {}
type Foo = Bar;
type Foo = Bar | Baz;
Open in Playground{ "allowAliases": "in-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowAliases": "in-intersections" }
option:
// primitives
type Foo = string & string[];
type Foo = `a-${number}` & `b-${number}`;
// reference types
interface Bar {}
class Baz implements Bar {}
type Foo = Bar & Baz;
Open in Playground{ "allowAliases": "in-unions-and-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowAliases": "in-unions-and-intersections" }
option:
// primitives
type Foo = 'a';
type Foo = string;
type Foo = `foo-${number}`;
// reference types
interface Bar {}
class Baz implements Bar {}
type Foo = Bar;
Open in Playground{ "allowAliases": "in-unions-and-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowAliases": "in-unions-and-intersections" }
option:
// primitives
type Foo = 'a' | 'b';
type Foo = string | string[];
type Foo = string & string[];
type Foo = `a-${number}` & `b-${number}`;
type Foo = `a-${number}` | `b-${number}`;
// reference types
interface Bar {}
class Baz implements Bar {}
type Foo = Bar | Baz;
type Foo = Bar & Baz;
Open in PlaygroundallowCallbacks
Whether to allow type aliases for callbacks. Default: "never"
.
该设置接受以下值:
¥The setting accepts the following values:
-
"always"
或"never"
用于激活或停用该功能。¥
"always"
or"never"
to active or deactivate the feature.
{ "allowCallbacks": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowCallbacks": "always" }
option:
type Foo = () => void;
type Foo = (name: string) => string;
class Person {}
type Foo = (name: string, age: number) => string | Person;
type Foo = (name: string, age: number) => string & Person;
Open in PlaygroundallowConditionalTypes
Whether to allow type aliases for conditional types. Default: "never"
.
{ "allowConditionalTypes": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowConditionalTypes": "always" }
option:
type Foo<T> = T extends number ? number : null;
Open in PlaygroundallowConstructors
Whether to allow type aliases with constructors. Default: "never"
.
该设置接受以下值:
¥The setting accepts the following values:
-
"always"
或"never"
用于激活或停用该功能。¥
"always"
or"never"
to active or deactivate the feature.
{ "allowConstructors": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowConstructors": "always" }
option:
type Foo = new () => void;
Open in PlaygroundallowLiterals
Whether to allow type aliases with object literal types. Default: "never"
.
该设置接受以下选项:
¥The setting accepts the following options:
-
"always"
或"never"
用于激活或停用该功能。¥
"always"
or"never"
to active or deactivate the feature. -
"in-unions"
,允许在联合语句中使用文字,例如type Foo = string | string[];
¥
"in-unions"
, allows literals in union statements, e.g.type Foo = string | string[];
-
"in-intersections"
,允许在交集语句中使用文字,例如type Foo = string & string[];
¥
"in-intersections"
, allows literals in intersection statements, e.g.type Foo = string & string[];
-
"in-unions-and-intersections"
,允许在联合和/或交集语句中使用文字。¥
"in-unions-and-intersections"
, allows literals in union and/or intersection statements.
{ "allowLiterals": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowLiterals": "always" }
options:
type Foo = {};
type Foo = {
name: string;
age: number;
};
type Foo = {
name: string;
age: number;
walk: (miles: number) => void;
};
type Foo = { name: string } | { age: number };
type Foo = { name: string } & { age: number };
Open in Playground{ "allowLiterals": "in-unions" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowLiterals": "in-unions" }
option:
type Foo = {};
type Foo = {
name: string;
age: number;
};
type Foo = {
name: string;
age: number;
walk: (miles: number) => void;
};
type Foo = { name: string } & { age: number };
Open in Playground{ "allowLiterals": "in-unions" }
选项的正确代码示例:
¥Examples of correct code for the { "allowLiterals": "in-unions" }
option:
type Foo = { name: string } | { age: number };
Open in Playground{ "allowLiterals": "in-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowLiterals": "in-intersections" }
option:
type Foo = {};
type Foo = {
name: string;
age: number;
};
type Foo = {
name: string;
age: number;
walk: (miles: number) => void;
};
type Foo = { name: string } | { age: number };
Open in Playground{ "allowLiterals": "in-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowLiterals": "in-intersections" }
option:
type Foo = { name: string } & { age: number };
Open in Playground{ "allowLiterals": "in-unions-and-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowLiterals": "in-unions-and-intersections" }
option:
type Foo = {};
type Foo = {
name: string;
age: number;
};
type Foo = {
name: string;
age: number;
walk: (miles: number) => void;
};
Open in Playground{ "allowLiterals": "in-unions-and-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowLiterals": "in-unions-and-intersections" }
option:
type Foo = { name: string } | { age: number };
type Foo = { name: string } & { age: number };
Open in PlaygroundallowMappedTypes
Whether to allow type aliases with mapped types. Default: "never"
.
该设置接受以下值:
¥The setting accepts the following values:
-
"always"
或"never"
用于激活或停用该功能。¥
"always"
or"never"
to active or deactivate the feature. -
"in-unions"
,允许在联合语句中使用别名,例如type Foo = string | string[];
¥
"in-unions"
, allows aliasing in union statements, e.g.type Foo = string | string[];
-
"in-intersections"
,允许在交集语句中使用别名,例如type Foo = string & string[];
¥
"in-intersections"
, allows aliasing in intersection statements, e.g.type Foo = string & string[];
-
"in-unions-and-intersections"
,允许在联合和/或交集语句中使用别名。¥
"in-unions-and-intersections"
, allows aliasing in union and/or intersection statements.
{ "allowMappedTypes": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowMappedTypes": "always" }
options:
type Foo<T> = { readonly [P in keyof T]: T[P] };
type Foo<T> = { [P in keyof T]?: T[P] };
type Foo<T, U> =
| { readonly [P in keyof T]: T[P] }
| { readonly [P in keyof U]: U[P] };
type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };
type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
readonly [P in keyof U]: U[P];
};
type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
Open in Playground{ "allowMappedTypes": "in-unions" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowMappedTypes": "in-unions" }
option:
type Foo<T> = { readonly [P in keyof T]: T[P] };
type Foo<T> = { [P in keyof T]?: T[P] };
type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
readonly [P in keyof U]: U[P];
};
type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
Open in Playground{ "allowMappedTypes": "in-unions" }
选项的正确代码示例:
¥Examples of correct code for the { "allowMappedTypes": "in-unions" }
option:
type Foo<T, U> =
| { readonly [P in keyof T]: T[P] }
| { readonly [P in keyof U]: U[P] };
type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };
Open in Playground{ "allowMappedTypes": "in-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowMappedTypes": "in-intersections" }
option:
type Foo<T> = { readonly [P in keyof T]: T[P] };
type Foo<T> = { [P in keyof T]?: T[P] };
type Foo<T, U> =
| { readonly [P in keyof T]: T[P] }
| { readonly [P in keyof U]: U[P] };
type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };
Open in Playground{ "allowMappedTypes": "in-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowMappedTypes": "in-intersections" }
option:
type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
readonly [P in keyof U]: U[P];
};
type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
Open in Playground{ "allowMappedTypes": "in-unions-and-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowMappedTypes": "in-unions-and-intersections" }
option:
type Foo<T> = { readonly [P in keyof T]: T[P] };
type Foo<T> = { [P in keyof T]?: T[P] };
Open in Playground{ "allowMappedTypes": "in-unions-and-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowMappedTypes": "in-unions-and-intersections" }
option:
type Foo<T, U> =
| { readonly [P in keyof T]: T[P] }
| { readonly [P in keyof U]: U[P] };
type Foo<T, U> = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] };
type Foo<T, U> = { readonly [P in keyof T]: T[P] } & {
readonly [P in keyof U]: U[P];
};
type Foo<T, U> = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] };
Open in PlaygroundallowTupleTypes
Whether to allow type aliases with tuple types. Default: "never"
.
该设置接受以下选项:
¥The setting accepts the following options:
-
"always"
或"never"
用于激活或停用该功能。¥
"always"
or"never"
to active or deactivate the feature. -
"in-unions"
,允许在联合语句中使用元组,例如type Foo = [string] | [string, string];
¥
"in-unions"
, allows tuples in union statements, e.g.type Foo = [string] | [string, string];
-
"in-intersections"
,允许在交集语句中使用元组,例如type Foo = [string] & [string, string];
¥
"in-intersections"
, allows tuples in intersection statements, e.g.type Foo = [string] & [string, string];
-
"in-unions-and-intersections"
,允许在联合和/或交集语句中使用元组。¥
"in-unions-and-intersections"
, allows tuples in union and/or intersection statements.
{ "allowTupleTypes": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowTupleTypes": "always" }
options:
type Foo = [number];
type Foo = [number] | [number, number];
type Foo = [number] & [number, number];
type Foo = [number] | ([number, number] & [string, string]);
Open in Playground{ "allowTupleTypes": "in-unions" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowTupleTypes": "in-unions" }
option:
type Foo = [number];
type Foo = [number] & [number, number];
type Foo = [string] & [number];
Open in Playground{ "allowTupleTypes": "in-unions" }
选项的正确代码示例:
¥Examples of correct code for the { "allowTupleTypes": "in-unions" }
option:
type Foo = [number] | [number, number];
type Foo = [string] | [number];
Open in Playground{ "allowTupleTypes": "in-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowTupleTypes": "in-intersections" }
option:
type Foo = [number];
type Foo = [number] | [number, number];
type Foo = [string] | [number];
Open in Playground{ "allowTupleTypes": "in-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowTupleTypes": "in-intersections" }
option:
type Foo = [number] & [number, number];
type Foo = [string] & [number];
Open in Playground{ "allowTupleTypes": "in-unions-and-intersections" }
选项的错误代码示例:
¥Examples of incorrect code for the { "allowTupleTypes": "in-unions-and-intersections" }
option:
type Foo = [number];
type Foo = [string];
Open in Playground{ "allowTupleTypes": "in-unions-and-intersections" }
选项的正确代码示例:
¥Examples of correct code for the { "allowTupleTypes": "in-unions-and-intersections" }
option:
type Foo = [number] & [number, number];
type Foo = [string] | [number];
Open in PlaygroundallowGenerics
Whether to allow type aliases with generic types. Default: "never"
.
该设置接受以下选项:
¥The setting accepts the following options:
-
"always"
或"never"
用于激活或停用该功能。¥
"always"
or"never"
to active or deactivate the feature.
{ "allowGenerics": "always" }
选项的正确代码示例:
¥Examples of correct code for the { "allowGenerics": "always" }
options:
type Foo = Bar<string>;
type Foo = Record<string, number>;
type Foo = Readonly<Bar>;
type Foo = Partial<Bar>;
type Foo = Omit<Bar, 'a' | 'b'>;
Open in Playground进一步阅读
¥Further Reading
'## 资源'