2017-04-13 3 views
0

Ich habe eine Schnittstelle Base, welche Schnittstellen und AB erstrecken und AB und beide haben Eigenschaften, die einzigartig sind und existieren nicht in dem anderes. In meinem Code, habe ich einige Daten, die abhängig von der Art verändern wird:Variablentyp angeben, nach anfänglicher Zuordnung in Maschinenschrift

interface Base { 
    basicProperty: any, 
    basicProperty2: any 
} 

interface A extends Base { 
    aSpecificProperty: any 
} 

interface B extends Base { 
    bSpecificProperty: any 
} 

function(type): A | B { 
    const data: A | B = { 
    basicProperty: 1, 
    basicProperty2: 2 
    } 

    if (type === 'A') { 
    // Data should be type A 
    data.aSpecificProperty = 3; 
    } else if (type === 'B') { 
    // Data should be type B 
    data.bSpecificProperty = 3; 
    } 

    return data; 
} 

Gibt es eine Möglichkeit, dies zu erreichen, ohne Typoskript über die Art beschwert nicht die richtigen Eigenschaften enthalten? Oder gibt es eine Möglichkeit, den Typ data von bis A oder B neu zuzuweisen?

Antwort

0

Es gibt viele Möglichkeiten, um das zu erreichen, was Sie wollen. Wenn Ihre Rückkehr auf type: string Argument basiert, verwenden warum nicht so etwas wie:

interface Base { } 
class A implements Base { name: string } 
class B implements Base { value: number } 

function fn(type): Base { 
    if (type == 'A') { 
    const data: A = { 
     name: 'abc' 
    } 
    //... 
    return data; 
    } 

    if (type == 'B') { 
    const data: B = { 
     value: 10 
    } 
    //... 
    return data; 
    } 
} 

ich weitere Informationen über Ihr Problem brauchen eine bessere Antwort zu geben, aber, da Sie eine Base Klasse haben, wie Sie gesagt haben, so etwas wie dieses könnte dir helfen.

UPDATE

Basierend auf Ihren Updates und Kommentare werde ich den folgenden Code vorschlagen:

interface Base { 
    basicProperty: any, 
    basicProperty2: any 
} 

interface A extends Base { 
    aSpecificProperty: any 
} 

interface B extends Base { 
    bSpecificProperty: any 
} 

function typeFactory<T extends Base>(obj: Base, ext: Partial<T>) { 
    return Object.assign(obj, ext) as T; 
} 

function myFn(type): A | B { 
    const data: Base = { 
    basicProperty: 1, 
    basicProperty2: 2 
    } 

    switch (type) { 
    case 'A': 
     return typeFactory<A>(data, { 
     aSpecificProperty: 3 
     }); 
    case 'B': 
     return typeFactory<B>(data, { 
     bSpecificProperty: 3 
     }); 
    } 
    // ... 
} 

Referenz über Object.assign(...)https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

+0

aussehen würde ich die Frage aktualisierte es ein wenig präziser über meinen Anwendungsfall zu machen. – josh

+0

Ok, ich habe es verstanden. Lassen Sie mich fragen, wie Sie das 'data' Objekt im' if' con Block erstellen, wie ich es vorgeschlagen habe, ist es eine Option für Sie? Andernfalls müssen Sie die 'data' als 'Base'-Schnittstelle deklarieren (' data: Base') und Sie müssen 'cast'-Operation verwenden, um den Typ innerhalb der' if'-Bedingung zu ändern. – Diullei

+0

Ich habe die Daten im obigen Beispiel vereinfacht, aber die Daten sind ein großes Objekt ... also wäre es eine Menge Duplizierung, wenn ich die Daten in jedem kopiere. Ich habe tatsächlich herausgefunden, was zu tun ist, indem ich auf deinen Vorschlag zum 'cast' schaue (ich erstelle die" Basisdaten "ohne Typ, dann erzeuge vars für A und B mit ihren jeweiligen Typen) und ordne sie in den if-Blöcken zu. Ist das sinnvoll? – josh

0

Haben Sie die typeof betrachtet mit Operator?

interface IBase { 
 
    name: string; 
 
    sayName(); 
 
    } 
 

 

 
class A implements IBase { 
 
    constructor(public name: string) { } 
 
    sayName() { 
 
     console.log(name); 
 
    } 
 

 
    onlyA() 
 
    { 
 
     console.log("I exist only in A"); 
 
    } 
 
} 
 

 
class B implements IBase { 
 
    constructor(public name: string) { } 
 
    sayName() { 
 
     console.log(name); 
 
    } 
 

 
    onlyB() 
 
    { 
 
     console.log("I exist only in B"); 
 
    } 
 
} 
 

 
function myFunc<T extends IBase>(arg: T) : any { 
 
    
 
    const data: T = arg; 
 

 
    if (typeof(data) === typeof(A)) { 
 
     // Data should be type A 
 
     data.sayName(); 
 
     let aObj: A = data as any; 
 
     aObj.onlyA(); 
 
    } else if (typeof(data) === typeof(B)) { 
 
     // Data should be type B 
 
     data.sayName(); 
 
     let bObj: B = data as any; 
 
     bObj.onlyB(); 
 
    } 
 

 
    return data; 
 
} 
 

 
let a = myFunc(new A("I am A")); 
 
let b = myFunc(new B("I am B")); 
 

 
a.onlyA(); 
 
b.onlyB();

Dies resultierte im Wesentlichen lassen Sie die generische Funktion, die Art überprüfen und geben ein Objekt vom Typ jede.

Haben Sie das gesucht oder ich habe die Frage nicht richtig beantwortet?

Per Ihrem Beispiel es so etwas wie

interface IBase{ 
 

 
} 
 

 
class A implements IBase { 
 

 
} 
 

 
class B implements IBase{ 
 

 
} 
 

 
function myFunc<T extends IBase>(type: T): A | B { 
 
    const data: A | B = { 
 

 
    } 
 

 
    if (typeof(type) === typeof(A)) { 
 
     // Data should be type A 
 
    } else if (typeof(type) === typeof(B)) { 
 
     // Data should be type B 
 
    } 
 

 
    return data; 
 
}

Verwandte Themen