Qual é a diferença entre essas instruções (interface x tipo)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Qual é a diferença entre essas instruções (interface x tipo)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Respostas:
Conforme a especificação da linguagem TypeScript :
Diferentemente de uma declaração de interface, que sempre introduz um tipo de objeto nomeado, uma declaração de alias de tipo pode introduzir um nome para qualquer tipo de tipo, incluindo tipos primitivos, de união e de interseção.
A especificação continua a mencionar:
Os tipos de interface têm muitas semelhanças com aliases de tipo para literais de tipo de objeto, mas, como os tipos de interface oferecem mais recursos, eles geralmente são preferidos aos aliases de tipo. Por exemplo, o tipo de interface
interface Point { x: number; y: number; }
poderia ser escrito como o alias do tipo
type Point = { x: number; y: number; };
No entanto, isso significa que os seguintes recursos são perdidos:
Uma interface pode ser nomeada em uma cláusula de extensão ou implementação, mas um alias de tipo para um literal de tipo de objeto não podemais ser verdadeiro desde o TS 2.7.- Uma interface pode ter várias declarações mescladas , mas um alias de tipo para um literal de tipo de objeto não pode.
interface Point { x: number; } interface Point { y: number; }
extends or implements
não é mais o caso. O tipo pode ser estendido e implementado por a class
. Aqui está um exemplo typescriptlang.org/play/…
As respostas atuais e a documentação oficial estão desatualizadas. E para os iniciantes no TypeScript, a terminologia usada não é clara sem exemplos. Abaixo está uma lista de diferenças atualizadas.
Ambos podem ser usados para descrever a forma de um objeto ou uma assinatura de função. Mas a sintaxe é diferente.
Interface
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
Alias do tipo
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
Ao contrário de uma interface, o alias de tipo também pode ser usado para outros tipos, como primitivos, uniões e tuplas.
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
Ambos podem ser estendidos, mas, novamente, a sintaxe é diferente. Além disso, observe que um alias de interface e tipo não é mutuamente exclusivo. Uma interface pode estender um alias de tipo e vice-versa.
Interface estende interface
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Alias de tipo estende alias de tipo
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
A interface estende o alias de tipo
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
O alias de tipo estende a interface
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
Uma classe pode implementar uma interface ou alias de tipo, ambos da mesma maneira exata. Observe, no entanto, que uma classe e uma interface são consideradas projetos estáticos. Portanto, eles não podem implementar / estender um alias de tipo que nomeie um tipo de união.
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;
}
Ao contrário de um alias de tipo, uma interface pode ser definida várias vezes e será tratada como uma única interface (com membros de todas as declarações sendo mescladas).
// 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 };
type
ou interface
? Ainda estou confuso sobre quando devo usar um ou outro.
type
determinadas limitações (e a partir do TypeScript 3.7 essas limitações também desapareceram). As interfaces podem estender tipos. Classes podem implementar tipos. Além disso, a apresentação de dados como captura de tela de uma tabela torna completamente inacessível para pessoas com visão prejudicada.
https://www.typescriptlang.org/docs/handbook/advanced-types.html
Uma diferença é que as interfaces criam um novo nome que é usado em qualquer lugar. Os aliases de tipo não criam um novo nome - por exemplo, mensagens de erro não usam o nome alternativo.
// cria uma estrutura em árvore para um objeto. Você não pode fazer o mesmo com a interface devido à falta de interseção (&)
type Tree<T> = T & { parent: Tree<T> };
// digite para restringir uma variável para atribuir apenas alguns valores. As interfaces não têm união (|)
type Choise = "A" | "B" | "C";
// graças aos tipos, você pode declarar o tipo NonNullable graças a um mecanismo condicional.
type NonNullable<T> = T extends null | undefined ? never : T;
// você pode usar a interface para OOP e 'implementa' para definir o esqueleto de objeto / 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)
}
}
// você pode estender interfaces com outras interfaces
interface IMyObject {
label: string,
}
interface IMyObjectWithSize extends IMyObject{
size?: number
}
Além das respostas brilhantes já fornecidas, há diferenças visíveis quando se trata de estender tipos versus interfaces. Recentemente, encontrei alguns casos em que uma interface não pode fazer o trabalho:
a documentação explicou
- Uma diferença é que as interfaces criam um novo nome que é usado em qualquer lugar. Os aliases de tipo não criam um novo nome - por exemplo, as mensagens de erro não usam o nome alternativo. Nas versões anteriores do TypeScript, os aliases de tipo não podiam ser estendidos ou implementados (nem estender / implementar outros tipos). A partir da versão 2.7, os aliases de tipo podem ser estendidos criando um novo tipo de interseção
- Por outro lado, se você não pode expressar alguma forma com uma interface e precisar usar um tipo de união ou de tupla, os aliases de tipo geralmente são o caminho a percorrer.