2017-11-28 2 views
1

ich diese Java Konstruktorüberladungen übersetzen müssen Typoskript:Typoskript: Konstruktor Überlastung

public QueryMixin() { 
    this(null, new DefaultQueryMetadata(), true); 
} 

public QueryMixin(QueryMetadata metadata) { 
    this(null, metadata, true); 
} 

public QueryMixin(QueryMetadata metadata, boolean expandAnyPaths) { 
    this(null, metadata, expandAnyPaths); 
} 

public QueryMixin(T self) { 
    this(self, new DefaultQueryMetadata(), true); 
} 

public QueryMixin(T self, QueryMetadata metadata) { 
    this(self, metadata, true); 
} 

public QueryMixin(T self, QueryMetadata metadata, boolean expandAnyPaths) {//...} 

Ich habe versucht, diese Konstrukteure schaffen einen Blick dort nehmen, aber ich habe nicht in der Lage, herauszufinden, wie zu erhalten Sie es ...

Irgendwelche Ideen?

constructor(); <<<1>>> 
constructor(metadata: QueryMetadata); 
constructor(metadata: QueryMetadata, expandAnyPaths: boolean); 
constructor(self: T); 
constructor(self: T, metadata: QueryMetadata); 
constructor(selfOrMetadata: T | QueryMetadata, expandAnyPaths: boolean) { 
    this.self = selfOrMetadata; <<< PROBLEM HERE 
    this.metadata = selfOrMetadata; <<< PROBLEM HERE 
    this.expandAnyPaths = expandAnyPaths; 
} 

Auf <<<1>>> Ich erhalte diese Compilation Nachricht:

Überlastsignatur mit Funktionsimplementierung nicht kompatibel ist.

+3

Nach einer Liste von Überladungen müssen Sie die tatsächliche Implementierungssignatur angeben, die (grob gesagt) eine Schnittmenge aller Überladungen sein muss, die ihr vorausgehen. Also in diesem Fall müssen Sie am Ende hinzufügen: 'Konstruktor (SelfOrMetaData ?: T | QueryMetadata ...)' und so weiter. Alternativ können Sie einfach den Vorwurf ablehnen, irgendeine Art von Sicherheit an diesem Punkt zu haben und einfach 'constructor (,,, args: any [])'. –

+0

Ich habe letzte Java-ähnliche Konstruktor-Implementierung hinzugefügt. Ich finde nicht recht heraus, wie man erkennen kann, ob "selfOrMetadata" zu "self" oder "metadata" zuweisbar ist. – Jordi

+0

Sie müssen beide Argumente optional machen ('selfOrMetaData?'), Da es mindestens eine Überladung gibt, bei der keines der Argumente angegeben wird. Ihr zweites Argument muss in ähnlicher Weise eine Vereinigung aller möglichen Argumenttypen in der zweiten Position sein. 'expandAnyPathsOrMetadata ?: boolean | QueryMetadata'. –

Antwort

2

Sie können die Konstruktorüberladungen erreichen Sie nach, aber Sie müssen eine Art durchführen Überprüfung, um sie geschehen ... Ich weiß nicht, was QueryMetadata aussieht, aber Sie sollten die Idee bekommen können, aus diesem in sich geschlossenen Beispiel.

Ich verwende eine Wache benutzerdefinierten Typ jene Union-Typen zu trennen:

interface QueryMetadata { 
    metadata: string; 
} 

function isQueryMetadata(obj: any): obj is QueryMetadata { 
    return (obj && obj.metadata); 
} 

class Example<T> { 

    private metadata: QueryMetadata; 
    private self: T; 
    private expandAnyPaths: boolean; 

    constructor(metadata: QueryMetadata); 
    constructor(metadata: QueryMetadata, expandAnyPaths: boolean); 
    constructor(self: T); 
    constructor(self: T, metadata: QueryMetadata); 
    constructor(selfOrMetadata: T | QueryMetadata, expandOrMetadata: boolean | QueryMetadata = false) { 
     if (isQueryMetadata(selfOrMetadata)) { 
      this.metadata = selfOrMetadata; 
     } else { 
      this.self = selfOrMetadata; 
     } 

     if (isQueryMetadata(expandOrMetadata)) { 
      this.metadata = expandOrMetadata; 
     } else { 
      this.expandAnyPaths = expandOrMetadata; 
     } 
    } 
} 

Factory Method Alternative

Wenn Sie etwas Neues schreiben, Sie könnten es vorziehen, eine Factory-Methode zu verwenden, um Ihre Klasse zu konstruieren ...

interface QueryMetadata { 
    metadata: string; 
} 

class Example<T> { 

    private metadata: QueryMetadata; 
    private self: T; 
    private expandAnyPaths: boolean; 

    protected constructor() { } 

    static fromMetadata<T>(metadata: QueryMetadata, expandAnyPaths: boolean = false) { 
     const example = new Example<T>(); 
     example.metadata = metadata; 
     example.expandAnyPaths = expandAnyPaths; 
    } 

    static fromSelf<T>(self: T, expandAnyPaths: boolean = false) { 
     const example = new Example<T>(); 
     example.self = self; 
     example.expandAnyPaths = expandAnyPaths; 
    } 
} 

const example1 = Example.fromSelf('Some Value'); 
const example2 = Example.fromSelf('Some Value', true); 
const example3 = Example.fromMetadata({ metadata: 'val' }); 
const example4 = Example.fromMetadata({ metadata: 'val' }, true); 
+0

Ich habe einen neuen Beitrag erstellt, um eine verwandte Frage zu [hier] zu erstellen (https://stackoverflow.com/questions/47635483/typescript-overloading-cascade-like-constructors). Der Unterschied ist, dass der letzte Konstrukteur alle Möglichkeiten sammeln muss. – Jordi

Verwandte Themen