AphrodyBun GitHub

Runtime docs · Linter · Rules

@typescript-eslint/no-type-alias

Disallow type aliases, or allow only some kinds of them

Some teams want object shapes written as interface and other types written out where they're used. This rule bans type aliases, and its options allow the kinds you still need.

With no options, every type declaration is reported. In a union or an intersection, each member is reported separately.

typescript-eslint has deprecated this rule.

Examples

Reported:

type UserId = string;

type User = {
  id: string;
};

type OnSave = (user: User) => void;

Not reported:

interface User {
  id: string;
}

interface OnSave {
  (user: User): void;
}

Options

Each option allows one kind of alias. It's "never" (default) or "always".

OptionWhat it allows
allowAliasesAnother name for a type: type Id = string, type Mode = "on", type Ids = string[], type Keys = keyof User.
allowLiteralsObject types: type User = { id: string }.
allowMappedTypesMapped types: type Flags = { [K in Keys]: boolean }.
allowTupleTypesTuples: type Point = [number, number].
allowCallbacksFunction types: type OnSave = () => void.
allowConstructorsConstructor types: type Ctor = new () => User.
allowConditionalTypesConditional types: type Item<T> = T extends (infer U)[] ? U : T.
allowGenericsA type with type arguments: type Users = Map<string, User>.

The first four also take "in-unions", "in-intersections" and "in-unions-and-intersections". These allow that kind only as a member of a union, of an intersection, or of either.

A common setup allows unions of names and literals, which an interface can't express:

type Status = "draft" | "published" | "archived";

An alias that isn't a union is still reported:

type Status = "draft";

When not to use it

Most TypeScript code uses aliases for unions, tuples, mapped types and conditional types, which you can't write any other way. If you only want interface instead of type for object shapes, use @typescript-eslint/consistent-type-definitions.