2017-06-16 3 views
4

Ich habe zwei unionierte Typen, einer hat eine Eigenschaft und der andere nicht. Ich ging davon aus, dass die Überprüfung der Existenz dieser Eigenschaft es mir erlauben würde, sie einzugrenzen, aber es funktioniert nicht.Eingeschränkter einfacher TypeScript-Union-Typ mit nicht definierter Eigenschaft

Ich habe erstellt this Playground repro. Diese andere very similar thing scheint gut zu funktionieren. Benutze ich die Gewerkschaften falsch?

Hier ist der Code für die der Vollständigkeit halber:

export interface AuthenticatedProfile { 
    readonly userId: string; 
    readonly name: string; 
} 
export interface AnonymousProfile { 
    readonly userId: undefined; 
    readonly otherProp: string; 
} 
export type Profile = AnonymousProfile | AuthenticatedProfile; 

function handleProfile(prof: Profile) { 
    if (prof.userId) { 
     console.log(prof.name); 
    } 
} 

Dank!

Antwort

3

Sie Typ Wachen können den Typ des prof Parameter zu beschränken.

export interface AuthenticatedProfile { 
    readonly userId: string; 
    readonly name: string; 
} 
export interface AnonymousProfile { 
    readonly userId: undefined; 
    readonly otherProp: string; 
} 
export type Profile = AnonymousProfile | AuthenticatedProfile; 

function isAuthenticatedProfile(prof: Profile): prof is AuthenticatedProfile { 
    return (<AuthenticatedProfile>prof).name !== undefined; 
} 

function isAnonymousProfile(prof: Profile): prof is AnonymousProfile { 
    return (<AnonymousProfile>prof).otherProp !== undefined; 
} 

function handleProfile(prof: Profile) { 
    if (isAuthenticatedProfile(prof)) { 
     console.log(prof.name); 
    } else if (isAnonymousProfile(prof)) { 
     console.log(prof.otherProp); 
    } 
} 

Sie können in den handbook mehr über Art Wachen in Typoskript im erweiterten Abschnitt Typen lesen.

+0

Ihre Lösung sieht gut aus. Ich habe nur eine Frage: Wenn die Eigenschaft userId Teil beider Typen ist und jeder Typ nur eine disjunkte Menge von Werten annehmen kann, warum kann dann TypScript den Typ nach meiner ursprünglichen Prüfung nicht ableiten? –

+0

für mich Aufruf 'prof.userId' funktioniert gut ohne jede Art Wachen. – toskv

+1

Es scheint tatsächlich ein bekanntes Problem zu sein. https://github.com/Microsoft/TypeScript/issues/12600. Ich weiß nicht, warum Sie den Fehler nicht sehen, es ist genau dort in der Spielplatz-Repro, die ich –

1

Sie können folgendes tun:

export interface AuthenticatedProfile { 
    readonly type: "AuthenticatedProfile"; 
    readonly userId: string; 
    readonly name: string; 
} 

export interface AnonymousProfile { 
    readonly type: "AnonymousProfile"; 
    readonly userId: undefined; 
    readonly otherProp: string; 
} 

export type Profile = AnonymousProfile | AuthenticatedProfile; 

function handleProfile(prof: Profile) { 
    if (prof.type === "AnonymousProfile") { 
     console.log(prof.name); // Error 
     console.log(prof.otherProp); // OK 
     console.log(prof.userId); // OK 
    } 
    if (prof.type === "AuthenticatedProfile") { 
     console.log(prof.name); // OK 
     console.log(prof.otherProp); // Error 
     console.log(prof.userId); // OK 
    } 
} 
+0

Es ist gut, diese Alternative zu kennen, aber ich bleibe bei der anderen Lösung, die meine Werte oder Typen nicht ändert. Aber ich habe eine Frage: Wenn die Eigenschaft userId Teil beider Typen ist und jeder Typ nur eine disjunkte Menge von Werten annehmen kann, warum kann dann TypScript den Typ nach meiner ursprünglichen Prüfung nicht ableiten? –

Verwandte Themen