type multiple interfaces array typescript

typescript - multiple - Mecanografiado: Interfaces vs Tipos



typescript type vs interface (6)

¿Cuál es la diferencia entre estas declaraciones (interfaz vs tipo)?

interface X { a: number b: string } type X = { a: number b: string };


Actualización 2019

Las respuestas actuales y la documentación oficial están desactualizadas. Y para aquellos nuevos en TypeScript, la terminología utilizada no está clara sin ejemplos. A continuación se muestra una lista de las diferencias actualizadas.

1. Objetos / funciones

Ambos se pueden usar para describir la forma de un objeto o una firma de función. Pero la sintaxis difiere.

Interfaz

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

Escriba alias

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

2. Otros tipos

A diferencia de una interfaz, el alias de tipo también se puede usar para otros tipos, como primitivas, uniones y tuplas.

// primitive type Name = string; // object type PartialPointX = { x: number; }; type PartialPointY = { y: number; }; // union type PartialPoint = PartialPointX | PartialPointY; // tuple type Data = [number, string];

3. Extender

Ambos se pueden extender, pero de nuevo, la sintaxis difiere. Además, tenga en cuenta que una interfaz y un alias de tipo no son mutuamente excluyentes. Una interfaz puede extender un alias de tipo, y viceversa.

La interfaz extiende la interfaz

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

El alias de tipo extiende el alias de tipo

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

La interfaz extiende el alias de tipo

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

El alias de tipo extiende la interfaz

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

4. Implementa

Una clase puede implementar una interfaz o un alias de tipo, ambos de la misma manera. Sin embargo, tenga en cuenta que una clase y una interfaz se consideran planos estáticos. Por lo tanto, no pueden implementar / extender un alias de tipo que nombre un tipo de unión.

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. Fusión de declaraciones

A diferencia de un alias de tipo, una interfaz se puede definir varias veces y se tratará como una única interfaz (con los miembros de todas las declaraciones fusionadas).

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


Ejemplos con tipos:

// crea una estructura de árbol para un objeto. No puede hacer lo mismo con la interfaz debido a la falta de intersección (&)

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

// escriba para restringir una variable para asignar solo unos pocos valores. Las interfaces no tienen unión (|)

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

// gracias a los tipos, puede declarar tipos no anulables gracias a un mecanismo condicional.

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

Ejemplos con interfaz:

// puedes usar la interfaz para OOP y usar ''implementos'' para definir el esqueleto de objeto / clase

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) } }

// puedes extender interfaces con otras interfaces

interface IMyObject { label: string, } interface IMyObjectWithSize extends IMyObject{ size?: number }


A partir de TypeScript 3.2 (noviembre de 2018), lo siguiente es cierto:


Según la especificación del lenguaje TypeScript :

A diferencia de una declaración de interfaz, que siempre introduce un tipo de objeto con nombre, una declaración de alias de tipo puede introducir un nombre para cualquier tipo de tipo, incluidos los tipos primitivos, de unión e intersección.

La especificación continúa mencionando:

Los tipos de interfaz tienen muchas similitudes con los alias de tipo para los literales de tipo de objeto, pero como los tipos de interfaz ofrecen más capacidades, generalmente se prefieren los alias de tipo. Por ejemplo, el tipo de interfaz

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

podría escribirse como el alias de tipo

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

Sin embargo, hacerlo significa que se pierden las siguientes capacidades:

  • Se puede nombrar una interfaz en una cláusula de extensiones o implementaciones, pero un alias de tipo para un literal de tipo de objeto ya no puede ser verdadero desde TS 2.7.
  • Una interfaz puede tener varias declaraciones fusionadas , pero un alias de tipo para un literal de tipo de objeto no puede.

la documentación ha explicado

  • Una diferencia es que las interfaces crean un nuevo nombre que se usa en todas partes. Los alias de tipo no crean un nombre nuevo; por ejemplo, los mensajes de error no usarán el nombre de alias. En versiones anteriores de TypeScript, los alias de tipo no se podían extender ni implementar (ni podían extender / implementar otros tipos). A partir de la versión 2.7, los alias de tipo pueden ampliarse creando un nuevo tipo de intersección
  • Por otro lado, si no puede expresar alguna forma con una interfaz y necesita usar un tipo de unión o tupla, los alias de tipo suelen ser el camino a seguir.

Interfaces versus alias de tipo