Qual è la differenza tra queste affermazioni (interfaccia vs tipo)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Qual è la differenza tra queste affermazioni (interfaccia vs tipo)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Risposte:
Secondo le specifiche del linguaggio TypeScript :
A differenza di una dichiarazione di interfaccia, che introduce sempre un tipo di oggetto denominato, una dichiarazione di alias di tipo può introdurre un nome per qualsiasi tipo di tipo, inclusi i tipi di primitiva, unione e intersezione.
Le specifiche continuano a menzionare:
I tipi di interfaccia hanno molte somiglianze con i tipi di alias per i letterali del tipo di oggetto, ma poiché i tipi di interfaccia offrono più funzionalità, in genere si preferisce digitare gli alias. Ad esempio, il tipo di interfaccia
interface Point { x: number; y: number; }
potrebbe essere scritto come alias del tipo
type Point = { x: number; y: number; };
Tuttavia, ciò significa che si perdono le seguenti funzionalità:
Un'interfaccia può essere nominata in una clausola extends o implementa, ma un alias di tipo per un tipo di oggetto letterale non puòpiù essere vero da TS 2.7.- Un'interfaccia può avere più dichiarazioni unite , ma un alias di tipo per un tipo di oggetto letterale non può.
interface Point { x: number; } interface Point { y: number; }
extends or implements
non sia più il caso. Il tipo può essere esteso e implementato da a class
. Ecco un esempio typescriptlang.org/play/…
Le risposte attuali e la documentazione ufficiale sono obsolete. E per chi non conosce TypeScript, la terminologia utilizzata non è chiara senza esempi. Di seguito è riportato un elenco di differenze aggiornate.
Entrambi possono essere usati per descrivere la forma di un oggetto o una firma di funzione. Ma la sintassi differisce.
Interfaccia
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
Digitare alias
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
A differenza di un'interfaccia, l'alias di tipo può essere utilizzato anche per altri tipi come primitive, sindacati e tuple.
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
Entrambi possono essere estesi, ma di nuovo la sintassi differisce. Inoltre, si noti che un'interfaccia e un alias di tipo non si escludono a vicenda. Un'interfaccia può estendere un alias di tipo e viceversa.
L'interfaccia estende l'interfaccia
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Alias di tipo estende l'alias di tipo
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
L'interfaccia estende l'alias di tipo
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
Digitare alias estende l'interfaccia
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
Una classe può implementare un'interfaccia o digitare un alias, entrambi nello stesso identico modo. Si noti tuttavia che una classe e un'interfaccia sono considerati progetti statici. Pertanto, non possono implementare / estendere un alias di tipo che denomina un tipo di unione.
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;
}
A differenza di un alias di tipo, un'interfaccia può essere definita più volte e verrà trattata come un'unica interfaccia (con i membri di tutte le dichiarazioni che vengono unite).
// 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
o interface
? Sono ancora confuso su quando dovrei usare l'uno o l'altro.
type
con alcune limitazioni (e a partire da TypeScript 3.7 anche queste limitazioni sono sparite). Le interfacce possono estendere i tipi. Le classi possono implementare tipi. Inoltre, presentare i dati come uno screenshot di una tabella li rende completamente inaccessibili alle persone con problemi di vista.
https://www.typescriptlang.org/docs/handbook/advanced-types.html
Una differenza è che le interfacce creano un nuovo nome che viene utilizzato ovunque. Gli alias di tipo non creano un nuovo nome, ad esempio i messaggi di errore non utilizzeranno il nome di alias.
// crea una struttura ad albero per un oggetto. Non puoi fare lo stesso con l'interfaccia a causa della mancanza di intersezione (&)
type Tree<T> = T & { parent: Tree<T> };
// digitare per limitare una variabile per assegnare solo pochi valori. Le interfacce non hanno unione (|)
type Choise = "A" | "B" | "C";
// grazie ai tipi, puoi dichiarare il tipo NonNullable grazie a un meccanismo condizionale.
type NonNullable<T> = T extends null | undefined ? never : T;
// puoi usare l'interfaccia per OOP e usare 'implements' per definire lo scheletro oggetto / 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)
}
}
// puoi estendere le interfacce con altre interfacce
interface IMyObject {
label: string,
}
interface IMyObjectWithSize extends IMyObject{
size?: number
}
Oltre alle brillanti risposte già fornite, ci sono notevoli differenze quando si tratta di estendere tipi e interfacce. Di recente ho incontrato un paio di casi in cui un'interfaccia non può fare il lavoro:
la documentazione ha spiegato
- Una differenza è che le interfacce creano un nuovo nome che viene utilizzato ovunque. Gli alias di tipo non creano un nuovo nome - ad esempio, i messaggi di errore non usano il nome di alias. Nelle versioni precedenti di TypeScript, gli alias di tipo non potevano essere estesi o implementati (né potevano estendere / implementare altri tipi). A partire dalla versione 2.7, gli alias di tipo possono essere estesi creando un nuovo tipo di intersezione
- D'altra parte, se non riesci ad esprimere una forma con un'interfaccia e devi usare un tipo di unione o tupla, gli alias di tipo sono di solito la strada da percorrere.