2016-03-30 15 views
2

Bitte bare mit mir, da ich ein Anfänger mit TypeScript bin.Generischen Typ in TypeScript erkennen

Ich schreibe eine einfache Methode, die eine Zeichenfolge als Argument akzeptiert, um als Schlüssel von einem Objekt zu suchen. Diese Methode hat einen generischen Typ, mit dem das zurückgegebene Objekt typisiert wird. Dies funktioniert jedoch nicht wie erwartet. Ist es tatsächlich möglich, Werte zu typisieren, und wenn ja, wie mache ich das?

class Application 
{ 
    private values : {[s : string] : string} = { 
     "foo" : "bar", 
     "test" : "1234" 
    } 

    public getValue<T>(key : string) : T 
    { 
     if (this.values.hasOwnProperty(key)) { 
      switch (typeof T) {     // Doesn't work 
       case "string": 
        return this.values[key].toString(); 
       case "number": 
        return parseInt(this.values[key]); 
       default: 
        throw new Error("Type of T is not a valid return type!"); 
      } 
     } else { 
      throw new Error("Key '" + key + "' does not exist!"); 
     } 
    } 
} 

var app : Application = new Application(); 
app.getValue<number>("test"); // Should return 1234 
app.getValue<string>("test"); // Should return '1234' 
+0

wie etwa die Überprüfung, nicht typeof T? – uksz

+0

@uksz die Variable 'Schlüssel' wird immer eine Zeichenkette sein, da ich auf Werte von einem Objekt zugreife, versuche ich so ziemlich meinen Code zu bekommen, um meinen Wert in das korrekte Format zu schreiben – Paradoxis

+1

Das ist nicht wirklich was Generika sind gemeint für: Ihre Liste ist alles andere als generisch. Gerade jetzt muss der Aufrufer wissen, wie er den resultierenden Wert interpretieren will. Warum also nicht einfach einen expliziten Parameter angeben? 'getValue (key: string, type: string) {switch (type) {// type switching}}'. Beachten Sie, dass, obwohl "T" ein Typ sein muss, Sie * diesen Typ * nicht verwenden, um den Wert zu verwenden: Sie nehmen nur verschiedene Aktionen vor, je nachdem, was der Aufrufer angefordert hat. Der explizite String-basierte Typ ist also ziemlich gleichwertig und hat den zusätzlichen Vorteil, dass er funktioniert. – dlev

Antwort

1

Ich glaube, Sie key und T in Ihrer Methode sind verwirrend. Ich würde es so schreiben:

public getValue<T>(key : string) : T 
{ 
    if (this.values.hasOwnProperty(key)) { 
     switch (typeof key) {     // Doesn't work 
      case "string": 
       return this.values[key].toString(); 
      case "number": 
       return parseInt(this.values[key]); 
      default: 
       throw new Error("Type of T is not a valid return type!"); 
     } 
    } else { 
     throw new Error("Key '" + key + "' does not exist!"); 
    } 
} 

Sie werden ein besseres Verständnis davon, wie Typoskript funktioniert durch playground verwenden. Sie können sehen, wie Ihr Code kompiliert:

var Application = (function() { 
function Application() { 
    this.values = { 
     "foo": "bar", 
     "test": "1234" 
    }; 
} 
Application.prototype.getValue = function (key) { 
    if (this.values.hasOwnProperty(key)) { 
     switch (typeof T) { 
      case "string": 
       return this.values[key].toString(); 
      case "number": 
       return parseInt(this.values[key]); 
      default: 
       throw new Error("Type of T is not a valid return type!"); 
     } 
    } 
    else { 
     throw new Error("Key '" + key + "' does not exist!"); 
    } 
}; 
return Application; 
}()); 
var app = new Application(); 
app.getValue("test"); // Should return 1234 
app.getValue("test"); // Should return '1234' 

Es gibt keine T in kompilierten JS ist. Es wird nur in Ihrem TypScript angezeigt, vorkompiliert.

Abgesehen davon sind Sie rufen nicht in der Lage: typeof Schlüssel

getValue<VALUE>(...) 
Verwandte Themen