Typescript: slå ihop 2 gränssnitt till 1
Jag har 2 gränssnitt:
export interface UploadAttemptBlocked {
type: 'UploadAttempt';
tab_id: string;
blocked: true;
}
export interface UploadAttemptAllowed {
type: 'UploadAttempt';
tab_id: string;
blocked: false;
filepath: string;
}
När blocked: true behöver jag inte filepath i gränssnittet. När blocked: false ska filepath vara där.
Hur kan jag slå samman dessa 2 gränssnitt till 1?
Svar #1
Det du letar efter kan inte göras med gränssnitten, men det är möjligt att göra med typer. Det kallas diskriminerade unionstyper.
Låt oss ha en separat typ för de vanliga fälten:
type UploadAttemptCommonFields = {
type: 'UploadAttempt';
tab_id: string;
};
Nu bör typen UploadAttempt se ut så här:
type UploadAttempt = UploadAttemptCommonFields & (Blocked | Unblocked)
Observera att parentesen är viktig för att säkerställa korrekt prioriteringsordning eftersom vi vill ha en union mellan Blocked och Unblocked.
Den sista typen:
type UploadAttemptCommonFields = {
type: 'UploadAttempt';
tab_id: string;
};
type UploadAttempt = UploadAttemptCommonFields &
(
| {
blocked: true;
}
| {
blocked: false;
filepath: string;
}
);
Svar #2
Även om wonderflames svar är korrekt, skulle jag för fullständighetens skull vilja påpeka att du också kan använda gränssnitt som din "diskriminatorbyggsten":
interface UploadAttemptBase {
type: 'UploadAttempt';
tab_id: string;
blocked: boolean;
}
export interface UploadAttemptBlocked extends UploadAttemptBase {
blocked: true;
}
export interface UploadAttemptAllowed extends UploadAttemptBase {
blocked: false;
filepath: string;
}
type UploadAttempt = UploadAttemptBlocked | UploadAttemptAllowed;
