angular - Hur kan jag få värdet på en egenskap av typen flera förenade gränssnittstyper?
Jag har följande kod:
const arrayFromForm: IFirst[] | ISecond[] | IThird[]; // = ... it's initialized
const arrayDB: IFirst[] | ISecond[] | IThird[]; // = ... it's initialized
const entitiesFromDb = arrayDB.filter(
(entity: IFirst | ISecond | IThird) =>
!(arrayFromForm.map(({ id }) => id))
.includes(entity.id)
);
Och den ger mig 1 fel: "Kartuttrycket kan inte anropas".
Rätta mig om jag har fel, men jag tror att detta beror på att det inte vet att det finns en egenskap som heter id i alla gränssnitt i unionen.
Jag har använt en typvakt tidigare, men jag tror att du bara kan skapa en typvakt mellan 2 typer i en union, eftersom du måste returnera en boolean?
Jag vill lösa detta problem med TypeScript (användardefinierad typvakt, typeof, instanceof, etc.), men jag är inte säker på om det är möjligt, eller hur? instanceof-typvakter kan inte skapas för gränssnitt, eller hur?
Vad är en bra lösning här?
REDIGERA: Jag har precis löst problemet med ett gränssnitt med de egenskaper som gränssnitten i unionen har gemensamt och jag ändrade bara typunionen till det nya gränssnittet. Detta är inte en särskilt bra lösning eftersom jag skulle vilja använda specifika metoder/egenskaper i de olika gränssnitten som jag skulle ha haft i typunionen.
Så jag tar inte bort frågan, eftersom det fortfarande är hjälpsamt att veta om det finns något som användardefinierade typvakter för typunioner med mer än 2 typer i dem.
Svar #1
Detta verkar vara ett känt problem i Typescript. Se här.
Men för tillfället kan du göra detta:
const arrayFromForm: IFirst[] | ISecond[] | IThird[]; // = ... it's initialized
const entitiesFromDb = arrayDB.filter(
(entity: IFirst | ISecond | IThird) =>
!(arrayFromForm as {id: number}[]).map(item => item.id).includes(entity.id) // Pay attention to the brackets
);
Vi tolkar arrayFromForm som endast en lämplig typ, istället för en union av typer. Detta är nära lösningen du kom fram till, men jag tycker det är lättare att underhålla på det här sättet.
Svar #2
Prova detta :-
const elementsIds = arrayFromForm.filter(arrItem => arrItem.id).map((item)=>item.id);
const entitiesFromDb = arrayDB.filter(
(entity: IFirst | ISecond | IThird) =>
!elementsIds.includes(entity.id)
)
