no-type-alias
型エイリアスを許可しない。
このルールは、@typescript-eslint/consistent-type-definitions
ルールに置き換えられ、非推奨となりました。TypeScriptの型エイリアスは、一般的に必要な言語機能です。それをすべて禁止することは、しばしば逆効果になります。
特定の種類の型エイリアスを禁止したい場合は、no-restricted-syntax
の使用を検討してください。トラブルシューティング & FAQ を参照してください。
TypeScriptでは、型エイリアスは3つの目的を果たします。
- 他の型のエイリアスを作成し、より単純な名前で参照できるようにする。
// 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;
一方、型エイリアスをインターフェースとして使用すると、次の機能が制限される可能性があります。
- コードの再利用性:インターフェースは、他の型によって拡張または実装できます。型エイリアスはできません。
- コードのデバッグ:インターフェースは新しい名前を作成するため、アプリケーションのデバッグ中にオブジェクトの基本型を簡単に識別できます。
最後に、型をマッピングすることは高度なテクニックであり、それをオープンにしておくと、アプリケーションで問題が発生する可能性があります。
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で開く