--- description: 'Disallow type aliases.' --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; > 🛑 This file is source code, not the primary documentation location! 🛑 > > See **https://typescript-eslint.io/rules/no-type-alias** for documentation. :::danger Deprecated This rule has been deprecated in favour of the [`@typescript-eslint/consistent-type-definitions`](./consistent-type-definitions.mdx) rule. TypeScript type aliases are a commonly necessary language feature; banning it altogether is oftentimes counterproductive. ::: :::note If you want to ban certain classifications of type aliases, consider using [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax). See [Troubleshooting & FAQs](/troubleshooting/faqs/general#how-can-i-ban-specific-language-feature). ::: In TypeScript, type aliases serve three purposes: - Aliasing other types so that we can refer to them using a simpler name. ```ts // 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. ```ts 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. ```ts type Immutable = { readonly [P in keyof T]: T[P] }; type Person = { name: string; age: number; }; type ImmutablePerson = Immutable; 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. ```ts // 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. ## Examples This rule disallows the use of type aliases in favor of interfaces and simplified types (primitives, tuples, unions, intersections, etc). ## Options ### `allowAliases` {/* insert option description */} The setting accepts the following values: - `"always"` or `"never"` to active or deactivate the feature. - `"in-unions"`, allows aliasing in union statements, e.g. `type Foo = string | string[];` - `"in-intersections"`, allows aliasing in intersection statements, e.g. `type Foo = string & string[];` - `"in-unions-and-intersections"`, allows aliasing in union and/or intersection statements. Examples of **correct** code for the `{ "allowAliases": "always" }` options: ```ts option='{ "allowAliases": "always" }' showPlaygroundButton // 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; ``` Examples of **incorrect** code for the `{ "allowAliases": "in-unions" }` option: ```ts option='{ "allowAliases": "in-unions" }' showPlaygroundButton // 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; ``` Examples of **correct** code for the `{ "allowAliases": "in-unions" }` option: ```ts option='{ "allowAliases": "in-unions" }' showPlaygroundButton // 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; ``` Examples of **incorrect** code for the `{ "allowAliases": "in-intersections" }` option: ```ts option='{ "allowAliases": "in-intersections" }' showPlaygroundButton // 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; ``` Examples of **correct** code for the `{ "allowAliases": "in-intersections" }` option: ```ts option='{ "allowAliases": "in-intersections" }' showPlaygroundButton // primitives type Foo = string & string[]; type Foo = `a-${number}` & `b-${number}`; // reference types interface Bar {} class Baz implements Bar {} type Foo = Bar & Baz; ``` Examples of **incorrect** code for the `{ "allowAliases": "in-unions-and-intersections" }` option: ```ts option='{ "allowAliases": "in-unions-and-intersections" }' showPlaygroundButton // primitives type Foo = 'a'; type Foo = string; type Foo = `foo-${number}`; // reference types interface Bar {} class Baz implements Bar {} type Foo = Bar; ``` Examples of **correct** code for the `{ "allowAliases": "in-unions-and-intersections" }` option: ```ts option='{ "allowAliases": "in-unions-and-intersections" }' showPlaygroundButton // 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; ``` ### `allowCallbacks` {/* insert option description */} The setting accepts the following values: - `"always"` or `"never"` to active or deactivate the feature. Examples of **correct** code for the `{ "allowCallbacks": "always" }` option: ```ts option='{ "allowCallbacks": "always" }' showPlaygroundButton 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; ``` ### `allowConditionalTypes` {/* insert option description */} Examples of **correct** code for the `{ "allowConditionalTypes": "always" }` option: ```ts option='{ "allowConditionalTypes": "always" }' showPlaygroundButton type Foo = T extends number ? number : null; ``` ### `allowConstructors` {/* insert option description */} The setting accepts the following values: - `"always"` or `"never"` to active or deactivate the feature. Examples of **correct** code for the `{ "allowConstructors": "always" }` option: ```ts option='{ "allowConstructors": "always" }' showPlaygroundButton type Foo = new () => void; ``` ### `allowLiterals` {/* insert option description */} The setting accepts the following options: - `"always"` or `"never"` to active or deactivate the feature. - `"in-unions"`, allows literals in union statements, e.g. `type Foo = string | string[];` - `"in-intersections"`, allows literals in intersection statements, e.g. `type Foo = string & string[];` - `"in-unions-and-intersections"`, allows literals in union and/or intersection statements. Examples of **correct** code for the `{ "allowLiterals": "always" }` options: ```ts option='{ "allowLiterals": "always" }' showPlaygroundButton 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 }; ``` Examples of **incorrect** code for the `{ "allowLiterals": "in-unions" }` option: ```ts option='{ "allowLiterals": "in-unions" }' showPlaygroundButton type Foo = {}; type Foo = { name: string; age: number; }; type Foo = { name: string; age: number; walk: (miles: number) => void; }; type Foo = { name: string } & { age: number }; ``` Examples of **correct** code for the `{ "allowLiterals": "in-unions" }` option: ```ts option='{ "allowLiterals": "in-unions" }' showPlaygroundButton type Foo = { name: string } | { age: number }; ``` Examples of **incorrect** code for the `{ "allowLiterals": "in-intersections" }` option: ```ts option='{ "allowLiterals": "in-intersections" }' showPlaygroundButton type Foo = {}; type Foo = { name: string; age: number; }; type Foo = { name: string; age: number; walk: (miles: number) => void; }; type Foo = { name: string } | { age: number }; ``` Examples of **correct** code for the `{ "allowLiterals": "in-intersections" }` option: ```ts option='{ "allowLiterals": "in-intersections" }' showPlaygroundButton type Foo = { name: string } & { age: number }; ``` Examples of **incorrect** code for the `{ "allowLiterals": "in-unions-and-intersections" }` option: ```ts option='{ "allowLiterals": "in-unions-and-intersections" }' showPlaygroundButton type Foo = {}; type Foo = { name: string; age: number; }; type Foo = { name: string; age: number; walk: (miles: number) => void; }; ``` Examples of **correct** code for the `{ "allowLiterals": "in-unions-and-intersections" }` option: ```ts option='{ "allowLiterals": "in-unions-and-intersections" }' showPlaygroundButton type Foo = { name: string } | { age: number }; type Foo = { name: string } & { age: number }; ``` ### `allowMappedTypes` {/* insert option description */} The setting accepts the following values: - `"always"` or `"never"` to active or deactivate the feature. - `"in-unions"`, allows aliasing in union statements, e.g. `type Foo = string | string[];` - `"in-intersections"`, allows aliasing in intersection statements, e.g. `type Foo = string & string[];` - `"in-unions-and-intersections"`, allows aliasing in union and/or intersection statements. Examples of **correct** code for the `{ "allowMappedTypes": "always" }` options: ```ts option='{ "allowMappedTypes": "always" }' showPlaygroundButton type Foo = { readonly [P in keyof T]: T[P] }; type Foo = { [P in keyof T]?: T[P] }; type Foo = | { readonly [P in keyof T]: T[P] } | { readonly [P in keyof U]: U[P] }; type Foo = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] }; type Foo = { readonly [P in keyof T]: T[P] } & { readonly [P in keyof U]: U[P]; }; type Foo = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] }; ``` Examples of **incorrect** code for the `{ "allowMappedTypes": "in-unions" }` option: ```ts option='{ "allowMappedTypes": "in-unions" }' showPlaygroundButton type Foo = { readonly [P in keyof T]: T[P] }; type Foo = { [P in keyof T]?: T[P] }; type Foo = { readonly [P in keyof T]: T[P] } & { readonly [P in keyof U]: U[P]; }; type Foo = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] }; ``` Examples of **correct** code for the `{ "allowMappedTypes": "in-unions" }` option: ```ts option='{ "allowMappedTypes": "in-unions" }' showPlaygroundButton type Foo = | { readonly [P in keyof T]: T[P] } | { readonly [P in keyof U]: U[P] }; type Foo = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] }; ``` Examples of **incorrect** code for the `{ "allowMappedTypes": "in-intersections" }` option: ```ts option='{ "allowMappedTypes": "in-intersections" }' showPlaygroundButton type Foo = { readonly [P in keyof T]: T[P] }; type Foo = { [P in keyof T]?: T[P] }; type Foo = | { readonly [P in keyof T]: T[P] } | { readonly [P in keyof U]: U[P] }; type Foo = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] }; ``` Examples of **correct** code for the `{ "allowMappedTypes": "in-intersections" }` option: ```ts option='{ "allowMappedTypes": "in-intersections" }' showPlaygroundButton type Foo = { readonly [P in keyof T]: T[P] } & { readonly [P in keyof U]: U[P]; }; type Foo = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] }; ``` Examples of **incorrect** code for the `{ "allowMappedTypes": "in-unions-and-intersections" }` option: ```ts option='{ "allowMappedTypes": "in-unions-and-intersections" }' showPlaygroundButton type Foo = { readonly [P in keyof T]: T[P] }; type Foo = { [P in keyof T]?: T[P] }; ``` Examples of **correct** code for the `{ "allowMappedTypes": "in-unions-and-intersections" }` option: ```ts option='{ "allowMappedTypes": "in-unions-and-intersections" }' showPlaygroundButton type Foo = | { readonly [P in keyof T]: T[P] } | { readonly [P in keyof U]: U[P] }; type Foo = { [P in keyof T]?: T[P] } | { [P in keyof U]?: U[P] }; type Foo = { readonly [P in keyof T]: T[P] } & { readonly [P in keyof U]: U[P]; }; type Foo = { [P in keyof T]?: T[P] } & { [P in keyof U]?: U[P] }; ``` ### `allowTupleTypes` {/* insert option description */} The setting accepts the following options: - `"always"` or `"never"` to active or deactivate the feature. - `"in-unions"`, allows tuples in union statements, e.g. `type Foo = [string] | [string, string];` - `"in-intersections"`, allows tuples in intersection statements, e.g. `type Foo = [string] & [string, string];` - `"in-unions-and-intersections"`, allows tuples in union and/or intersection statements. Examples of **correct** code for the `{ "allowTupleTypes": "always" }` options: ```ts option='{ "allowTupleTypes": "always" }' showPlaygroundButton type Foo = [number]; type Foo = [number] | [number, number]; type Foo = [number] & [number, number]; type Foo = [number] | ([number, number] & [string, string]); ``` Examples of **incorrect** code for the `{ "allowTupleTypes": "in-unions" }` option: ```ts option='{ "allowTupleTypes": "in-unions" }' showPlaygroundButton type Foo = [number]; type Foo = [number] & [number, number]; type Foo = [string] & [number]; ``` Examples of **correct** code for the `{ "allowTupleTypes": "in-unions" }` option: ```ts option='{ "allowTupleTypes": "in-unions" }' showPlaygroundButton type Foo = [number] | [number, number]; type Foo = [string] | [number]; ``` Examples of **incorrect** code for the `{ "allowTupleTypes": "in-intersections" }` option: ```ts option='{ "allowTupleTypes": "in-intersections" }' showPlaygroundButton type Foo = [number]; type Foo = [number] | [number, number]; type Foo = [string] | [number]; ``` Examples of **correct** code for the `{ "allowTupleTypes": "in-intersections" }` option: ```ts option='{ "allowTupleTypes": "in-intersections" }' showPlaygroundButton type Foo = [number] & [number, number]; type Foo = [string] & [number]; ``` Examples of **incorrect** code for the `{ "allowTupleTypes": "in-unions-and-intersections" }` option: ```ts option='{ "allowTupleTypes": "in-unions-and-intersections" }' showPlaygroundButton type Foo = [number]; type Foo = [string]; ``` Examples of **correct** code for the `{ "allowTupleTypes": "in-unions-and-intersections" }` option: ```ts option='{ "allowTupleTypes": "in-unions-and-intersections" }' showPlaygroundButton type Foo = [number] & [number, number]; type Foo = [string] | [number]; ``` ### `allowGenerics` {/* insert option description */} The setting accepts the following options: - `"always"` or `"never"` to active or deactivate the feature. Examples of **correct** code for the `{ "allowGenerics": "always" }` options: ```ts option='{ "allowGenerics": "always" }' showPlaygroundButton type Foo = Bar; type Foo = Record; type Foo = Readonly; type Foo = Partial; type Foo = Omit; ``` {/* Intentionally Omitted: When Not To Use It */} ## Further Reading - [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html)