Typescript: интерфейсы против типов

296

В чем разница между этими утверждениями (интерфейс против типа)?

interface X {
    a: number
    b: string
}

type X = {
    a: number
    b: string
};
  • 2
    Нашел эту статью с объяснением различий - medium.com/@martin_hotell/…
Теги:

4 ответа

334
Лучший ответ

В соответствии с TypeScript Спецификацией языка:

В отличие от декларации интерфейса, которая всегда вводит именованный тип объекта, объявление псевдонима типа может вводить имя для любого типа, включая типы примитива, объединения и пересечения.

Далее указывается:

Типы интерфейсов имеют много общего с типами псевдонимов для типа объекта литералов, но поскольку типы интерфейсов предлагают больше возможностей, они обычно предпочитают вводить псевдонимы. Например, тип интерфейса

interface Point {
    x: number;
    y: number;
}

может быть записан как псевдоним типа

type Point = {
    x: number;
    y: number;
};

Однако, это означает, что теряются следующие возможности:

  • Интерфейс может быть назван в выражении extends или implement, но псевдоним типа для литерала типа объекта не может.
  • Интерфейс может иметь несколько объединенных объявлений, но псевдоним типа для литерала типа объекта не может.
  • 58
    Что означает «множественные объединенные объявления» во втором разнице?
  • 2
    @jrahhali Я думаю, что дополненный сценарий в этой ветке SO отвечает на ваш вопрос
Показать ещё 9 комментариев
50

2019 Обновление


Текущие ответы и официальная документация устарели. А для новичков в TypeScript используемая терминология непонятна без примеров. Ниже приведен список актуальных различий.

1. Объекты/Функции

И то, и другое можно использовать для описания формы объекта или сигнатуры функции. Но синтаксис отличается.

Интерфейс

interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}

Введите псевдоним

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;

2. Другие типы

В отличие от интерфейса, псевдоним типа может также использоваться для других типов, таких как примитивы, объединения и кортежи.

// primitive
type Name = string;

// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];

3. Расширить

Оба могут быть расширены, но, опять же, синтаксис отличается. Кроме того, обратите внимание, что интерфейс и псевдоним типа не являются взаимоисключающими. Интерфейс может расширять псевдоним типа, и наоборот.

Интерфейс расширяет интерфейс

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

Тип псевдоним расширяет тип псевдоним

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

Интерфейс расширяет псевдоним типа

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }

Тип псевдоним расширяет интерфейс

interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

4. Реализует

Класс может реализовывать интерфейс или псевдоним типа, оба одинаково точно. Обратите внимание, что класс и интерфейс считаются статическими чертежами. Поэтому они не могут реализовать/расширить псевдоним типа, который называет тип объединения.

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x: 1;
  y: 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x: 1;
  y: 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x: 1;
  y: 2;
}

5. Декларация о слиянии

В отличие от псевдонима типа, интерфейс может быть определен несколько раз и будет рассматриваться как единый интерфейс (с элементами всех объединенных объявлений).

// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };
  • 10
    Это обеспечивает более подробную информацию о том, как использовать тип против интерфейса.
  • 1
    Если официальная документация устарела, где можно подтвердить предоставленную вами информацию?
Показать ещё 2 комментария
23

https://www.typescriptlang.org/docs/handbook/advanced-types.html

Одно отличие состоит в том, что интерфейсы создают новое имя, которое используется повсюду. Типа aliases не создают нового имени - например, сообщения об ошибках не будут использовать псевдоним.

  • 9
    Теперь это устарело и больше не соответствует истине начиная с TypeScript 2.1. Увидеть. medium.com/@martin_hotell/...
2

Начиная с TypeScript 3.2, верно следующее:

Изображение 3461

  • 1
    Не могли бы вы предоставить больше информации о том, как была сгенерирована предоставленная вами таблица / изображение? например, исходный код или ссылки на документацию
  • 0
    Конечно! Это таблица уценок, созданная GitHub. Вы можете найти синтаксис здесь: help.github.com/articles/organizing-information-with-tables . Если вы заинтересованы в самом контенте, это из моих личных заметок. Я, наверное, должен уточнить и привести примеры, но это очень долго читать.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню