Typescript literal birleşimleri
İki literal türüm var ve B'yi A birleşiminden çıkarmak istiyorum.
type A = 'a' | 'b'
type B = 'a'
Bunu böyle yaptığımda:
type MyExclude<A2, B2> = A2 extends B2 ? never : A2
type C2 = MyExclude<A, B>
// C2 = 'b'
Doğru çalışıyor, yani 'b' alıyorum.
Ama bunu doğrudan böyle yaptığımda:
type C = A extends B ? never : A
// C = 'a' | 'b'
Önemli değil. Bunu bir aracı genel tür aracılığıyla mı yoksa doğrudan mı yaptığımın ne önemi var ki?
Teşekkürler.
Cevap #1
Bunu generic olarak yaptığınızda, Typescript bu kontrolü birlik içindeki her üyeye dağıtarak uygulayacak. Yani type C2=MyExclude<A, B>, 'a | b' extends 'a' ? never : 'a | 'b' olarak değerlendirilmez, bunun yerine ('a' extends 'a' ? never : 'a') | ('b' extends 'a' ? never : 'b') olarak değerlendirilir. 'a', B'yi genişletiyor, bu yüzden sonuç never olur. 'b' B'yi genişletmiyor, bu yüzden sonuç 'b' olur. Ve nihai sonuç never | 'b', yani sadece 'b' olur.
Dağıtıcı kısmı, eğer bu bir generic değilse gerçekleşmez. type C=A extends B ? never : A sadece bir kez değerlendirilecek, 'a | b' extends 'a' ? never : 'a | b' olarak. 'a' | 'b', 'a''yı kapsamaz, bu yüzden sonuç tüm tip olur, 'a' | 'b'
Dağıtıcı koşullu türlere bakın
Dağıtıcı koşullu türler
Kontrol edilen türün çıplak bir tür parametresi olduğu koşullu türlere dağıtıcı koşullu türler denir. Dağıtıcı koşullu türler, örnekleme sırasında birleşim türleri üzerinde otomatik olarak dağıtılır. Örneğin,
T extends U ? X : YifadesininTiçinA | B | Ctür argümanı ile örneklenmesi,(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)olarak çözülür.