跳至主要內容

no-type-alias

不允許類型別名。

已棄用

此規則已被棄用,改用 @typescript-eslint/consistent-type-definitions 規則。TypeScript 類型別名是一種常用的必要語言功能;完全禁止它通常會適得其反。

注意

如果您想禁止某些類型的類型別名,請考慮使用 no-restricted-syntax。請參閱 疑難排解與常見問題解答

在 TypeScript 中,類型別名有三個用途

  • 為其他類型建立別名,以便我們可以使用更簡單的名稱來引用它們。
// 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;
}) {
// ...
}
  • 充當類似介面的角色,提供一組必須存在於實作該類型的物件中的方法和屬性。
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();
  • 充當類型之間的映射工具,允許快速修改。
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

建立別名時,類型別名不會建立新的類型,它只是建立一個新的名稱來引用原始類型。因此,為原始類型和其他簡單類型、元組、聯合或交集建立別名有時可能是多餘的。

// this doesn't make much sense
type myString = string;

另一方面,使用類型別名作為介面可能會限制您

  • 重複使用您的程式碼:介面可以由其他類型擴展或實作。類型別名則不行。
  • 除錯您的程式碼:介面會建立一個新的名稱,因此在除錯應用程式時很容易識別物件的基本類型。

最後,映射類型是一種高級技術,將其開放可能會迅速成為應用程式中的痛點。

.eslintrc.cjs
module.exports = {
"rules": {
"@typescript-eslint/no-type-alias": "error"
}
};

在 Playground 中試試這個規則 ↗

範例

此規則不允許使用類型別名,而是建議使用介面和簡化的類型(原始類型、元組、聯合、交集等)。

選項

此規則接受以下選項

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',
allowLiterals: 'never',
allowMappedTypes: 'never',
allowTupleTypes: 'never',
allowGenerics: 'never',
},
];

allowAliases

這適用於原始類型和參考類型。

此設定接受以下值

  • "always""never" 來啟用或停用此功能。
  • "in-unions",允許在聯合語句中建立別名,例如 type Foo = string | string[];
  • "in-intersections",允許在交集語句中建立別名,例如 type Foo = string & string[];
  • "in-unions-and-intersections",允許在聯合和/或交集語句中建立別名。

{ "allowAliases": "always" } 選項的正確程式碼範例

// 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;
在 Playground 中開啟

{ "allowAliases": "in-unions" } 選項的錯誤程式碼範例

// 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;
在 Playground 中開啟

{ "allowAliases": "in-unions" } 選項的正確程式碼範例

// 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;
在 Playground 中開啟

{ "allowAliases": "in-intersections" } 選項的錯誤程式碼範例

// 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;
在 Playground 中開啟

{ "allowAliases": "in-intersections" } 選項的正確程式碼範例

// primitives
type Foo = string & string[];

type Foo = `a-${number}` & `b-${number}`;

// reference types
interface Bar {}
class Baz implements Bar {}

type Foo = Bar & Baz;
在 Playground 中開啟

{ "allowAliases": "in-unions-and-intersections" } 選項的錯誤程式碼範例

// primitives
type Foo = 'a';

type Foo = string;

type Foo = `foo-${number}`;

// reference types
interface Bar {}
class Baz implements Bar {}

type Foo = Bar;
在 Playground 中開啟

{ "allowAliases": "in-unions-and-intersections" } 選項的正確程式碼範例

// 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;
在 Playground 中開啟

allowCallbacks

這適用於函數類型。

此設定接受以下值

  • "always""never" 來啟用或停用此功能。

{ "allowCallbacks": "always" } 選項的正確程式碼範例

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;
在 Playground 中開啟

allowConditionalTypes

這適用於條件類型。

{ "allowConditionalTypes": "always" } 選項的正確程式碼範例

type Foo<T> = T extends number ? number : null;
在 Playground 中開啟

allowConstructors

這適用於建構函數類型。

此設定接受以下值

  • "always""never" 來啟用或停用此功能。

{ "allowConstructors": "always" } 選項的正確程式碼範例

type Foo = new () => void;
在 Playground 中開啟

allowLiterals

這適用於字面量類型 (type Foo = { ... })。

此設定接受以下選項

  • "always""never" 來啟用或停用此功能。
  • "in-unions",允許在聯合語句中使用字面量,例如 type Foo = string | string[];
  • "in-intersections",允許在交集語句中使用字面量,例如 type Foo = string & string[];
  • "in-unions-and-intersections",允許在聯合和/或交集語句中使用字面量。

{ "allowLiterals": "always" } 選項的正確程式碼範例

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 };
在 Playground 中開啟

{ "allowLiterals": "in-unions" } 選項的錯誤程式碼範例

type Foo = {};

type Foo = {
name: string;
age: number;
};

type Foo = {
name: string;
age: number;
walk: (miles: number) => void;
};

type Foo = { name: string } & { age: number };
在 Playground 中開啟

{ "allowLiterals": "in-unions" } 選項的正確程式碼範例

type Foo = { name: string } | { age: number };
在 Playground 中開啟

{ "allowLiterals": "in-intersections" } 選項的錯誤程式碼範例

type Foo = {};

type Foo = {
name: string;
age: number;
};

type Foo = {
name: string;
age: number;
walk: (miles: number) => void;
};

type Foo = { name: string } | { age: number };
在 Playground 中開啟

{ "allowLiterals": "in-intersections" } 選項的正確程式碼範例

type Foo = { name: string } & { age: number };
在 Playground 中開啟

{ "allowLiterals": "in-unions-and-intersections" } 選項的錯誤程式碼範例

type Foo = {};

type Foo = {
name: string;
age: number;
};

type Foo = {
name: string;
age: number;
walk: (miles: number) => void;
};
在 Playground 中開啟

{ "allowLiterals": "in-unions-and-intersections" } 選項的正確程式碼範例

type Foo = { name: string } | { age: number };

type Foo = { name: string } & { age: number };
在 Playground 中開啟

allowMappedTypes

這適用於字面量類型。

此設定接受以下值

  • "always""never" 來啟用或停用此功能。
  • "in-unions",允許在聯合語句中建立別名,例如 type Foo = string | string[];
  • "in-intersections",允許在交集語句中建立別名,例如 type Foo = string & string[];
  • "in-unions-and-intersections",允許在聯合和/或交集語句中建立別名。

{ "allowMappedTypes": "always" } 選項的正確程式碼範例

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] };
在 Playground 中開啟

{ "allowMappedTypes": "in-unions" } 選項的錯誤程式碼範例

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] };
在 Playground 中開啟

{ "allowMappedTypes": "in-unions" } 選項的正確程式碼範例

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] };
在 Playground 中開啟

{ "allowMappedTypes": "in-intersections" } 選項的錯誤程式碼範例

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] };
在 Playground 中開啟

{ "allowMappedTypes": "in-intersections" } 選項的正確程式碼範例

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] };
在 Playground 中開啟

{ "allowMappedTypes": "in-unions-and-intersections" } 選項的錯誤程式碼範例

type Foo<T> = { readonly [P in keyof T]: T[P] };

type Foo<T> = { [P in keyof T]?: T[P] };
在 Playground 中開啟

{ "allowMappedTypes": "in-unions-and-intersections" } 選項的正確程式碼範例

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] };
在 Playground 中開啟

allowTupleTypes

這適用於元組類型 (type Foo = [number])。

此設定接受以下選項

  • "always""never" 來啟用或停用此功能。
  • "in-unions",允許在聯合語句中使用元組,例如 type Foo = [string] | [string, string];
  • "in-intersections",允許在交集語句中使用元組,例如 type Foo = [string] & [string, string];
  • "in-unions-and-intersections",允許在聯合和/或交集語句中使用元組。

{ "allowTupleTypes": "always" } 選項的正確程式碼範例

type Foo = [number];

type Foo = [number] | [number, number];

type Foo = [number] & [number, number];

type Foo = [number] | ([number, number] & [string, string]);
在 Playground 中開啟

{ "allowTupleTypes": "in-unions" } 選項的錯誤程式碼範例

type Foo = [number];

type Foo = [number] & [number, number];

type Foo = [string] & [number];
在 Playground 中開啟

{ "allowTupleTypes": "in-unions" } 選項的正確程式碼範例

type Foo = [number] | [number, number];

type Foo = [string] | [number];
在 Playground 中開啟

{ "allowTupleTypes": "in-intersections" } 選項的錯誤程式碼範例

type Foo = [number];

type Foo = [number] | [number, number];

type Foo = [string] | [number];
在 Playground 中開啟

{ "allowTupleTypes": "in-intersections" } 選項的正確程式碼範例

type Foo = [number] & [number, number];

type Foo = [string] & [number];
在 Playground 中開啟

{ "allowTupleTypes": "in-unions-and-intersections" } 選項的錯誤程式碼範例

type Foo = [number];

type Foo = [string];
在 Playground 中開啟

{ "allowTupleTypes": "in-unions-and-intersections" } 選項的正確程式碼範例

type Foo = [number] & [number, number];

type Foo = [string] | [number];
在 Playground 中開啟

allowGenerics

這適用於泛型類型,包括 TypeScript 提供的全局工具類型 (type Foo = Record<string, number>)。

此設定接受以下選項

  • "always""never" 來啟用或停用此功能。

{ "allowGenerics": "always" } 選項的正確程式碼範例

type Foo = Bar<string>;

type Foo = Record<string, number>;

type Foo = Readonly<Bar>;

type Foo = Partial<Bar>;

type Foo = Omit<Bar, 'a' | 'b'>;
在 Playground 中開啟

延伸閱讀

資源