set - Navngiving av TypeScript union- og snittyper
Jeg kan ikke forstå logikken bak begrepene intersection types og union types i TypeScript. Jeg tenker på grensesnitt (eller klasser) som mengder av egenskaper.
Den logiske konjunksjonsoperatoren & tilsvarer snitt i mengdelære, definert som:
Snittet av to mengder A og B er mengden som inneholder alle elementene i A som også tilhører B
I TypeScript bygges også en Intersection Type ved å bruke &-operatoren og defineres som:
Snitt-typen til grensesnittet
Colorfulog grensesnittetCircleer en ny type som har alle medlemmene tilColorfulogCircle
Dette er det nøyaktige motsatte av hvordan snitt er definert i matematikk og mengdelære.
Jeg er sikker på at det finnes en annen måte å se det på, men jeg klarer ikke å finne den ut.
Svar #1
Her er en annen måte å tenke på det på. Tenk på fire sett: Blå ting, røde ting, store ting og små ting.
Hvis du skjærer settet av alle blå ting med alle små ting, ender du opp med foreningen av egenskapene - alt i settet har både den blå egenskapen og den lille egenskapen.
Men hvis du tok unionen av blå små ting og røde små ting, er det bare litenhets-egenskapen som er universell i det resulterende settet. Å snitte «blå små» med «røde små» gir «små».
Med andre ord, å ta unionen av verdidomenet gir et skjærende sett med egenskaper, og omvendt.
I bildeform:
Svar #2
Typen A | B refererer til objekter som er enten A eller B. Med andre ord, verdier av en slik type hentes fra unionen av verdier for A og verdier for B.
Typen A & B refererer til objekter som er både A og B. Med andre ord, verdier av slik type kommer fra snittet av verdier for A og verdier for B.
Navngivningen og semantikken er identiske i andre språk som C++.
Svar #3
Du må ikke tenke på typer som sett av objektattributter i dette tilfellet. Vi kan unngå forvirringen om hvordan union- og snitt-typer fungerer ved å se på skalarvariabler og deres sett med tillatte verdier (i stedet for objekter):
type A = 1 | 2
type B = 2 | 3
type I = A & B
type U = A | B
let a: A
let b: B
let i: I
let u: U
a = 1
a = 2
a = 3 // <- error
b = 1 // <- error
b = 2
b = 3
i = 1 // <- error
i = 2
i = 3 // <- error
u = 1
u = 2
u = 3
Her tilsvarer begrepene «union» og «snitt» nøyaktig settteoribegrepene når de brukes på mengdene av tillatte verdier.
Å anvende begrepet tillatte verdier (instanser) på objekttyper er litt mer utfordrende (fordi mengdelærens analogi ikke fungerer så godt):
type A = {
x: number
y: number
}
type B = {
y: number
z: number
}
type I = A & B
type U = A | B
- En variabel av typen
Akan holde objektinstanser med egenskapenexogy(og ingen andre egenskaper). - En variabel av typen
Bkan inneholde objektforekomster med egenskaperyogz(og ingen andre egenskaper). - I mengdelære er snittet av de to mengdene av objektinstanser ovenfor tomt. Imidlertid kan en variabel av snittype
Iinneholde objekter med egenskaper fra typeAOG typeB(dvs.x,yogz; derav symbolet&) som tilsvarer unionen av egenskapene til de to typene (derav forvirringen). - I mengdelære inkluderer unionen av de to settene med objektinstanser ovenfor ikke objekter med alle tre egenskapene. Imidlertid kan en variabel av unionstype
Uholde objekter med egenskapene til typeAELLER de av typeB(logisk OR, ikke XOR, dvs.xogy,yogz, ellerx,yogz; derfor symbolet|) noe som innebærer at snittet av egenskapene til de to typene (yi vårt eksempel) er garantert å være til stede (derav forvirringen).
let i: I
let u: U
i = { x: 1, y: 2 }; // <- error
i = { y: 2, z: 3 }; // <- error
i = { x: 1, y: 2, z: 3 };
u = { x: 1, y: 2 };
u = { y: 2, z: 3 };
u = { x: 1, y: 2, z: 3 };
Svar #4
Forvirringen her stammer sannsynligvis fra hvordan vi forestiller oss mengdene, nemlig at vi tenker på snittet/unionen som involverer medlemmene av typene i stedet for typene selv. Jeg satte sammen en grafikk som forhåpentligvis klargjør konseptet:

