web-dev-qa-db-fra.com

Typescript: Interfaces vs types

Quelle est la différence entre ces instructions (interface vs type)?

interface X {
    a: number
    b: string
}

type X = {
    a: number
    b: string
};
451
user6101582

Selon le Spécification du langage TypeScript :

Contrairement à une déclaration d’interface, qui introduit toujours un type d’objet nommé, une déclaration d’alias de type peut introduire un nom pour tout type de type, y compris primitive, union, et types d'intersection.

La spécification continue à mentionner:

Les types d'interface présentent de nombreuses similitudes avec les alias de type des littéraux de type d'objet, mais étant donné que les types d'interface offrent davantage de fonctionnalités, ils sont généralement préférés aux alias de type. Par exemple, le type d'interface

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

pourrait être écrit comme l'alias de type

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

Cependant, cela signifie que les capacités suivantes sont perdues:

  • Une interface peut être nommée dans une clause extended ou implements, mais un alias de type pour un objet littéral ne peut pas Ce n'est plus vrai depuis TS 2.7.
  • Une interface peut avoir plusieurs déclarations fusionnées , mais un alias de type pour un objet de type littéral ne le peut pas.
434

Mise à jour 2019


Les réponses actuelles et le documentation officielle sont obsolètes. Et pour ceux qui découvrent TypeScript, la terminologie utilisée n’est pas claire sans exemples. Vous trouverez ci-dessous une liste des différences les plus récentes.

1. Objets/Fonctions

Les deux peuvent être utilisés pour décrire la forme d'un objet ou une signature de fonction. Mais la syntaxe diffère.

Interface

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

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

Tapez un alias

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

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

2. Autres types

Contrairement à une interface, le type alias peut également être utilisé pour d'autres types tels que les primitives, les unions et les tuples.

// primitive
type Name = string;

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

// union
type PartialPoint = PartialPointX | PartialPointY;

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

3. Étendre

Les deux peuvent être étendus, mais là encore, la syntaxe est différente. En outre, notez qu'une interface et un alias de type ne sont pas mutuellement exclusifs. Une interface peut étendre un alias de type, et inversement.

Interface étend l'interface

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

Le type alias étend le type alias

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

L'interface étend le type alias

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

Le type alias étend l'interface

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

4. met en œuvre

Une classe peut implémenter une interface ou un alias de type, les deux de la même manière. Notez cependant qu'une classe et une interface sont considérées comme des plans statiques. Par conséquent, ils ne peuvent pas implémenter/étendre un alias de type qui nomme un type d'union.

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. Déclaration fusionnant

Contrairement à un alias de type, une interface peut être définie plusieurs fois et sera traitée comme une interface unique (avec les membres de toutes les déclarations en cours de fusion).

// 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 };
338
jabacchetta

À compter de TypeScript 3.2 (nov. 2018), ce qui suit est vrai:

enter image description here

56
Karol Majewski

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

Une différence est que les interfaces créent un nouveau nom qui est utilisé partout. Les alias de type ne créent pas de nouveau nom. Par exemple, les messages d'erreur n'utilisent pas le nom d'alias.

25
nickf

Exemples avec types:

// crée une arborescence pour un objet. Vous ne pouvez pas faire la même chose avec l'interface à cause du manque d'intersection (&)

type Tree<T> = T & { parent: Tree<T> };

// tapez pour restreindre une variable à n'affecter que quelques valeurs. Les interfaces n'ont pas d'union (|)

type Choise = "A" | "B" | "C";

// grâce aux types, vous pouvez déclarer le type NonNullable grâce à un mécanisme conditionnel.

type NonNullable<T> = T extends null | undefined ? never : T;

Exemples avec interface:

// vous pouvez utiliser l'interface pour OOP et utiliser 'implements' pour définir le squelette d'objet/classe

interface IUser {
    user: string;
    password: string;
    login: (user: string, password: string) => boolean;
}

class User implements IUser {
    user = "user1"
    password = "password1"

    login(user: string, password: string) {
        return (user == user && password == password)
    }
}

// vous pouvez étendre des interfaces avec d'autres interfaces

    interface IMyObject {
        label: string,
    }

    interface IMyObjectWithSize extends IMyObject{
        size?: number
    }
2

la documentation a expliqué

  • Une différence est que les interfaces créent un nouveau nom qui est utilisé partout. Les alias de type ne créent pas de nouveau nom. Par exemple, les messages d'erreur n'utilisent pas le nom d'alias. Dans les versions antérieures de TypeScript, les alias de type ne pouvaient pas être étendus ni implémentés (ils ne pouvaient pas non plus étendre/implémenter d'autres types). A partir de la version 2.7, les alias de types peuvent être étendus en créant un nouveau type d'intersection
  • D'autre part, si vous ne pouvez pas exprimer une forme avec une interface et que vous devez utiliser un type d'union ou de tuple, les alias de type sont généralement la solution.

Interfaces contre type alias

0
Liu Lei