Menu

TypeScript Intersection Tipler: Tipleri & ile Birleştirmek

A & B şeklindeki bir intersection tip, aynı anda hem A hem B olan bir değeri tanımlar, yani ikisinin de her üyesine sahiptir. Nesne tiplerini & ile birleştirmeyi, çakışan özelliklerin neden never olduğunu, union intersection'larının neden yalnızca ortak üyeleri tuttuğunu ve ne zaman extends kullanılacağını öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

A & B şeklinde yazılan bir intersection tip, aynı anda hem bir A hem bir B olan bir değeri tanımlar. Nesne tipleri için bu, değerin ikisinin de her özelliğine sahip olması demektir. Mevcut tipleri, özellikleri yeniden yazmadan bu şekilde birleştirirsiniz.

İkinci nesne team özelliğini atlıyor, bu yüzden TS2322 derleme hatası veriyor; mesajın sonraki satırı da Property 'team' is missing ... but required in type 'Employee' diyor. Bir Staff değeri, bir Person veya bir Employee beklenen her yere verilebilir.

Nesne Tiplerini Birleştirmek

&, type alias'ların, interface'lerin ve satır içi nesne tiplerinin her karışımıyla, ayrıca generic tip parametreleriyle çalışır. Yerini doldurmanın zor olduğu yer bu son durumdur: aldığı her nesneye özellik ekleyen bir fonksiyon bunu kesin olarak ifade edebilir.

Çağıran, verdiği şeyin tam tipini (title, words) ve eklenen iki özelliği korur. Bir interface ... extends "T ne olursa olsun, artı bunlar" diyemez, çünkü bir interface bir tip parametresini genişletemez.

Çakışan Özellikler never Olur

İki taraf da aynı özelliği bildirdiğinde özelliğin tipi ikisinin intersection'ı olur. Bu tiplerin ortak hiçbir değeri yoksa özellik never olur ve derleyici siz bir değer oluşturmaya çalışana kadar hiçbir şey söylemez:

index.ts(7,22): error TS2322: Type 'string' is not assignable to type 'never'.

Hata, ona neden olan tipi değil nesneyi gösterir; bu da bu hataların izini sürmeyi yavaşlatır. Editörde r.id üzerine gelmek tipini gösterir: never. Çakışan özellik bir literal etiket olduğunda, örneğin type Shape = { kind: "circle" } & { kind: "square" }, TypeScript daha da ileri gider ve intersection'ın tamamını never tipine indirger. Böyle bir değerin bir özelliğini okumak da nedenini açıklar: Property 'kind' does not exist on type 'never'. The intersection 'Shape' was reduced to 'never' because property 'kind' has conflicting types in some constituents.

interface ... extends ise aynı çakışmayı TS2430 hatasıyla bildirimde yakalar. İkisi arasındaki ana pratik fark budur; interface ile type sayfası onları yan yana karşılaştırıyor.

Uyumlu Örtüşmeler Özelliği Daraltır

İki özellik tipi örtüşüyorsa sonuç örtüşen kısımdır. Bu bir hata değil, işe yarar bir şeydir:

İkinci yarı & işaretinin union'lara ne yaptığını gösteriyor: iki tarafın ortak üyelerini tutar. Tipleri değer kümeleri olarak düşünmek bunu öngörülebilir kılar. A | B iki kümenin birleşimi, A & B kesişimleridir; içinde hiçbir şey olmayan bir kesişim de never olur.

Intersection ile Union

Adlar küme teorisinden gelir ve nesne özelliklerine uygulandığında ters görünür:

A | B (union)A & B (intersection)
Bir değerbir A ya da bir Bbir A ve bir B
İzin verilen değer kümesidaha büyükdaha küçük
Kullanabileceğiniz özellikleryalnızca ikisinde de olanlarikisinden de hepsi
number ile stringstring | numbernever
"b" | "c" ile "a" | "b""a" | "b" | "c""b"

Nesne tiplerinin bir intersection'ı, tam da daha az değere izin verdiği için daha fazla özelliğe sahiptir: yalnızca her şeye sahip nesneler.

Intersection ile extends

type C = A & Binterface C extends A, B
Çalıştığı tiplerunion'lar ve tip parametreleri dahil her tipüyeleri statik olarak bilinen nesne tipleri
Çakışan özelliksessizce never olurbildirimde TS2430 veya TS2320 hatası
Sonuçbileşen bileşen kontrol edilen bir intersectionilişkileri önbelleğe alınan tek ve düz, adlandırılmış bir tip
Büyük birleşimlertip kontrolünü yavaşlatabilirTypeScript wiki'sinin Performance sayfasınca tercih edilir

Birkaç nesne type alias'ını birleştirmek için & alışılmış ve uygundur. Pek çok parçadan oluşturulan bir tip ya da public bir API tipi için extends daha erken hatalar ve daha ucuz tip kontrolleri sağlar.

Primitive'lerle Intersection'lar: Branding

Bir primitive'i bir nesne tipiyle kesiştirmek never üretmez: string & { readonly __brand: "UserId" }, fazladan ve yalnızca derleme zamanına ait bir işaret taşıyan bir string'dir. Hiçbir gerçek string o özelliğe sahip değildir ve asıl amaç da budur: yalnızca brand'i bilerek assert eden kod bir tane oluşturabilir; böylece düz bir string ya da bir OrderId artık UserId beklenen yere verilemez. Bu tekniğin kendi sayfası var: branded tipler.

Sıkça Sorulan Sorular

TypeScript'te intersection tip nedir?

A & B şeklinde yazılan ve değerlerinin aynı anda hem A hem B tipini karşılaması gereken bir tiptir. Nesne tipleri için bu, değerin A tipinin her özelliğine ve B tipinin her özelliğine sahip olması demektir. İki type alias'ı tek bir tipte birleştirmenin alışılmış yolu budur.

Union ile intersection arasındaki fark nedir?

Bir union A | B "ikisinden biri" anlamına gelir: değer bir A ya da bir B olabilir ve daraltana kadar yalnızca ortak olanları kullanabilirsiniz. Bir intersection A & B ise "ikisi birden" anlamına gelir: değer ikisinden de her şeye sahiptir. Nesne tiplerinde union daha fazla değer kabul eder, intersection ise daha fazla özelliğe sahiptir.

Intersection tipim neden never?

Çünkü hiçbir değer iki tarafı birden karşılayamıyor. string & number sonucu never olur; { id: string } & { id: number } ise id özelliğini bir string & number yapar, yani özellik never olur ve hiçbir nesne oluşturulamaz. İki nesne tipi aynı literal etiketi farklı değerlerle taşıyorsa (kind: "circle" ve kind: "square") intersection'ın tamamı never tipine indirgenir.

Intersection mı yoksa extends mi kullanmalıyım?

İkisi de nesne tiplerini birleştirir. interface X extends A, B çakışan özellikleri bildirimde bildirir ve büyük nesne tiplerini oluşturmak için TypeScript ekibi tarafından önerilir. & ise union'lar ve generic parametreler dahil her tiple çalışır; extends bunları birleştiremez. Type alias'lar ve generic yardımcılar için &, interface oluştururken extends kullanın.

TypeScript'te iki nesne tipi nasıl birleştirilir?

type Merged = A & B yazın. Çalışma zamanındaki değer için iki nesneyi de yayın: const merged: A & B = { ...a, ...b }. A ve B farklı tiplerde bir özelliği paylaşıyorsa o özelliğin tipi never olur; ikinci nesnenin özellikleri birincininkilerin yerini alacaksa Omit<A, keyof B> & B kullanın.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA