TypeScript: Arayüzler ve Türler


Yanıtlar:


578

Gereğince typescript Dil Şartname :

Her zaman adlandırılmış nesne türünü tanıtan bir arabirim bildiriminin aksine, bir tür takma ad bildirimi , ilkel, birleşim ve kesişim türleri de dahil olmak üzere her türlü tür için bir ad verebilir.

Spesifikasyondan bahsetmeye devam ediyoruz:

Arabirim türleri , nesne türü değişmezleri için tür takma adlarıyla birçok benzerliğe sahiptir, ancak arabirim türleri daha fazla özellik sunduğundan, genellikle tür takma adlarına tercih edilir. Örneğin, arayüz türü

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

tür takma adı olarak yazılabilir

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

Ancak, bunu yapmak aşağıdaki yeteneklerin kaybolduğu anlamına gelir:

  • Bir arabirim bir genişletme veya uygulama yan tümcesinde adlandırılabilir, ancak nesne türü değişmezi için bir tür diğer adı TS 2.7'den beri artık doğru olamaz .
  • Bir arabirim birden çok birleştirilmiş bildirime sahip olabilir , ancak nesne türü değişmezi için bir tür diğer adı olamaz.

109
İkinci farkta "çoklu birleştirilmiş bildirimler" ne anlama geliyor?
jrahhali

66
@jrahhali arayüzü iki kez tanımlarsanız, typcript onları bir araya getirir.
Andrey Fedorov

39
@jrahhali türünü iki kez tanımlarsanız, typescript size hata verir
Andrey Fedorov

18
@jrahhaliinterface Point { x: number; } interface Point { y: number; }
Nahuel Greco

20
İlk nokta extends or implementsartık böyle değil. Tip a ile genişletilebilir ve uygulanabilir class. İşte bir tür typescriptlang.org/play/…
dark_ruby

783

2019 Güncellemesi


Mevcut cevaplar ve resmi belgeler eski. TypeScript'te yeni olanlar için, kullanılan terminoloji örnekler olmadan net değildir. Güncel farklılıkların listesi aşağıdadır.

1. Nesneler / İşlevler

Her ikisi de bir nesnenin şeklini veya işlev imzasını tanımlamak için kullanılabilir. Ancak sözdizimi farklıdır.

Arayüz

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

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

Diğer ad yazın

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

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

2. Diğer Türler

Bir arabirimden farklı olarak, tür takma adı, ilkel öğeler, birlikler ve tuples gibi diğer türler için de kullanılabilir.

// primitive
type Name = string;

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

// union
type PartialPoint = PartialPointX | PartialPointY;

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

3. Uzatın

Her ikisi de genişletilebilir, ancak yine sözdizimi farklıdır. Ayrıca, bir arabirim ve tür diğer adının birbirini dışlamadığını unutmayın. Bir arabirim bir tür takma adını genişletebilir ya da tam tersi olabilir.

Arayüz arayüzü genişletir

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

Tür takma adı, tür takma adını genişletir

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

Arabirim tür takma adını genişletir

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

Tür takma adı arabirimi genişletir

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

4. Uygular

Sınıf, her ikisi de aynı şekilde bir arabirim veya tür takma adı uygulayabilir. Ancak, bir sınıf ve arabirimin statik planlar olarak kabul edildiğini unutmayın. Bu nedenle, birleşim türünü adlandıran bir tür takma adı uygulayamaz / genişletemezler.

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. Beyanın birleştirilmesi

Tür takma adından farklı olarak, bir arayüz birden çok kez tanımlanabilir ve tek bir arayüz olarak değerlendirilir (tüm bildirimlerin üyeleri birleştirilir).

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

9
Resmi belgeler eskiyse, verdiğiniz bilgiler nerede teyit edilebilir?
iX3

61
Bu gönderiye dayanarak, tür takma adı üzerinden bir arabirim seçmenin tek nedeni, arabirimlerin bildirim birleştirme (nokta 5) özelliğini kullanmak istemenizdir. Bunun ötesinde, eşdeğerler (ve tür takma adlarının daha özlü sözdizimi sunduğunu iddia ediyorum).
maxedison

17
Ben her zaman nesne türü değişmez için arabirimler kullanarak, aksi takdirde türleri kullanarak daha mantıklı, ayrıca beyan birleştirme zaten kullanılmaması gerektiğini düşünüyorum, aslında asla bir arabirimin bazı projenin başka bir dosyasında bildirildiğini beklemeyeceğim ekstra özellikler, tip kontrolü, bu ninja benzeri arayüzlerle hayatınızı zorlaştırmamak için hayatınızı kolaylaştırmak için yapılır: D
Ahmed Kamal

9
Yani aslında, gerçekten rahat hissettiğimiz şey için "neredeyse kişisel" bir seçim mi? Bunun bir nedeni dışında, typeveya interface? Birini veya diğerini ne zaman kullanacağım konusunda hala kafam karıştı.
Joseph Briggs

7
Birisi neden arayüz birleştirmeyi istediğiniz konusunda biraz motivasyon sağlayabilir mi? Bu benim için potansiyel olarak kafa karıştırıcı görünüyor. Arayüzünüzün tanımını neden farklı bloklara yaymak istiyorsunuz?
Vanquish46

95

TypeScript 3.2 (Kasım 2018) itibarıyla aşağıdakiler doğrudur:

resim açıklamasını buraya girin


9
Lütfen sağladığınız tablonun / resmin nasıl oluşturulduğu hakkında daha fazla bilgi verebilir misiniz? örneğin kaynak kodu veya dokümantasyon bağlantıları
iX3

23
evet, içeriğin kaynağı demekti, sunumunu değil.
iX3

3
Ben inanmıyorum sınıf edebilirsiniz uzatmak bir türü veya bir arayüz ya, ben gerçekten isteyeyim neden göremiyorum ??
Dan King

7
Metin görüntülerini göndermekten kaçının, bunun yerine gerçek metni doğrudan gönderinize ekleyin. Metin görüntüleri kolayca ayrıştırılamaz veya aranamaz ve görme engelli kullanıcılar tarafından erişilemez.
Andrew Marshall

2
Bu tabloda, içeriğini destekleyecek herhangi bir kaynak yoktur ve buna güvenmem. Örneğin, typebelirli sınırlamalarla özyinelemeli türleri tanımlayabilirsiniz (ve TypeScript 3.7'den itibaren bu sınırlamalar da gider). Arabirimler türleri genişletebilir. Sınıflar türleri uygulayabilir. Ayrıca, verileri bir tablonun ekran görüntüsü olarak sunmak, görme bozukluğu olan kişiler için tamamen erişilemez olmasını sağlar.
Michał Miszczyszyn


5

Tipli Örnekler:

// bir nesne için bir ağaç yapısı oluşturun. Kavşak eksikliği nedeniyle aynı şeyi arayüzle yapamazsınız (&)

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

// bir değişkeni yalnızca birkaç değer atamakla sınırlamak için yazın. Arabirimlerin birliği yoktur (|)

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

// türler sayesinde, koşullu bir mekanizma sayesinde Nullenemez türü bildirebilirsiniz.

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

Arayüz ile Örnekler:

// OOP için arayüz kullanabilir ve nesne / sınıf iskeletini tanımlamak için 'implements' kullanabilirsiniz

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

// diğer arayüzlerle arayüzleri genişletebilirsiniz

    interface IMyObject {
        label: string,
    }

    interface IMyObjectWithSize extends IMyObject{
        size?: number
    }


-2

belgeler açıkladı

  • Bir fark, arayüzlerin her yerde kullanılan yeni bir ad oluşturmasıdır. Tür takma adları yeni bir ad oluşturmaz - örneğin, hata iletileri takma ad adını kullanmaz. TypeScript'in eski sürümlerinde, tür takma adları genişletilemez veya uygulanamaz (veya diğer türleri genişletemez / uygulayamaz). 2.7 sürümünden itibaren, tür takma adları yeni bir kavşak türü oluşturularak genişletilebilir
  • Öte yandan, bir arabirimle bir şekli ifade edemiyorsanız ve bir birleşim veya tuple tipi kullanmanız gerekiyorsa, tür takma adları genellikle gitmenin yoludur.

Arabirimler ve Tür Takma Adları

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.