Apa perbedaan antara pernyataan ini (antarmuka vs tipe)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Apa perbedaan antara pernyataan ini (antarmuka vs tipe)?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
Jawaban:
Sesuai dengan Spesifikasi Bahasa TypeScript :
Tidak seperti deklarasi antarmuka, yang selalu memperkenalkan jenis objek bernama, deklarasi alias tipe dapat memperkenalkan nama untuk semua jenis jenis, termasuk tipe primitif, gabungan, dan persimpangan.
Spesifikasi selanjutnya menyebutkan:
Jenis antarmuka memiliki banyak kesamaan untuk mengetik alias untuk literal jenis objek, tetapi karena jenis antarmuka menawarkan lebih banyak kemampuan, mereka biasanya lebih suka mengetik alias. Misalnya, tipe antarmuka
interface Point { x: number; y: number; }
dapat ditulis sebagai jenis alias
type Point = { x: number; y: number; };
Namun, melakukannya berarti kemampuan berikut hilang:
Antarmuka dapat diberi nama dalam perluasan atau penerapan klausa, tetapi jenis alias untuk tipe objek literal tidak bisalagi benar sejak TS 2.7.- Antarmuka dapat memiliki beberapa deklarasi digabungkan , tetapi alias tipe untuk tipe objek literal tidak bisa.
interface Point { x: number; } interface Point { y: number; }
extends or implements
tidak lagi menjadi masalah. Jenis dapat diperpanjang dan diimplementasikan oleh a class
. Berikut ini contoh typescriptlang.org/play/…
Jawaban saat ini dan dokumentasi resmi sudah usang. Dan bagi mereka yang baru mengenal TypeScript, terminologi yang digunakan tidak jelas tanpa contoh. Di bawah ini adalah daftar perbedaan terbaru.
Keduanya dapat digunakan untuk menggambarkan bentuk objek atau fungsi tanda tangan. Tetapi sintaksnya berbeda.
Antarmuka
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
Ketik alias
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
Tidak seperti antarmuka, jenis alias juga dapat digunakan untuk jenis lain seperti primitif, serikat pekerja, dan tupel.
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
Keduanya dapat diperpanjang, tetapi sekali lagi, sintaksnya berbeda. Selain itu, perhatikan bahwa antarmuka dan jenis alias tidak saling eksklusif. Antarmuka dapat memperluas alias tipe, dan sebaliknya.
Antarmuka memperluas antarmuka
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Jenis alias meluas alias jenis
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
Antarmuka memperluas alias tipe
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
Ketik alias memperluas antarmuka
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
Kelas dapat mengimplementasikan antarmuka atau ketik alias, keduanya dengan cara yang persis sama. Namun perlu dicatat bahwa kelas dan antarmuka dianggap cetak biru statis. Oleh karena itu, mereka tidak dapat mengimplementasikan / memperluas jenis alias yang menamai jenis serikat.
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;
}
Tidak seperti jenis alias, antarmuka dapat didefinisikan beberapa kali, dan akan diperlakukan sebagai antarmuka tunggal (dengan anggota semua deklarasi digabungkan).
// 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
atau interface
? Saya masih bingung kapan harus menggunakan yang satu atau yang lain.
type
dengan batasan tertentu (dan pada TypeScript 3.7 batasan ini juga hilang). Antarmuka dapat memperluas tipe. Kelas dapat mengimplementasikan tipe. Selain itu, menyajikan data sebagai tangkapan layar dari tabel membuatnya benar-benar tidak dapat diakses oleh orang-orang dengan gangguan penglihatan.
https://www.typescriptlang.org/docs/handbook/advanced-types.html
Satu perbedaan adalah antarmuka membuat nama baru yang digunakan di mana-mana. Ketik alias tidak membuat nama baru - misalnya, pesan kesalahan tidak akan menggunakan nama alias.
// buat struktur pohon untuk objek. Anda tidak dapat melakukan hal yang sama dengan antarmuka karena kurangnya persimpangan (&)
type Tree<T> = T & { parent: Tree<T> };
// ketik untuk membatasi variabel untuk menetapkan hanya beberapa nilai. Antarmuka tidak memiliki penyatuan (|)
type Choise = "A" | "B" | "C";
// terima kasih pada tipe, Anda dapat mendeklarasikan tipe NonNullable berkat mekanisme kondisional.
type NonNullable<T> = T extends null | undefined ? never : T;
// Anda dapat menggunakan antarmuka untuk OOP dan menggunakan 'implement' untuk mendefinisikan objek / kerangka kelas
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)
}
}
// Anda dapat memperluas antarmuka dengan antarmuka lain
interface IMyObject {
label: string,
}
interface IMyObjectWithSize extends IMyObject{
size?: number
}
Selain jawaban brilian yang telah disediakan, ada perbedaan nyata dalam hal memperluas tipe vs antarmuka. Saya baru-baru ini mengalami beberapa kasus di mana antarmuka tidak dapat melakukan pekerjaan:
dokumentasi telah dijelaskan
- Satu perbedaan adalah antarmuka membuat nama baru yang digunakan di mana-mana. Ketik alias tidak membuat nama baru - misalnya, pesan kesalahan tidak akan menggunakan nama alias. Dalam versi lama dari TypeScript, ketik alias tidak dapat diperpanjang atau diimplementasikan dari (atau mereka tidak dapat memperpanjang / mengimplementasikan jenis lain). Pada versi 2.7, alias alias dapat diperluas dengan membuat tipe persimpangan baru
- Di sisi lain, jika Anda tidak bisa mengekspresikan bentuk dengan antarmuka dan Anda perlu menggunakan jenis gabungan atau tuple, ketik alias biasanya merupakan cara yang harus dilakukan.