2016-03-30 4 views
2

Прошу вас, как я начинаю с TypeScript.Обнаружение общего типа в TypeScript

Я пишу простой метод, который принимает строку в качестве аргумента для поиска в качестве ключа от объекта. Этот метод имеет общий тип, который будет использоваться для вывода возвращаемого объекта. Однако это работает не так, как ожидалось. Действительно ли это возможно для значений типа, и если да, то как это сделать?

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

как о проверке TYPEOF ключ, не TYPEOF T? – uksz

+0

@uksz переменная 'key' всегда будет строкой, так как я получаю доступ к значениям от объекта, я почти просто пытаюсь получить свой код, чтобы придать значение моей версии правильному формату – Paradoxis

+1

Это не совсем то, что генерики предназначенный для: ваш список не является общим. Прямо сейчас, вызывающий должен знать, как он хочет интерпретировать результирующее значение, так почему бы просто не сделать это явным параметром? 'getValue (key: string, type: string) {switch (type) {// type switching}}'. Обратите внимание, что даже если 'T' должен быть типом, вы на самом деле не используете * этот тип для указания значения: вы просто выполняете разные действия в зависимости от того, что запросил вызывающий. Таким образом, явный строковый тип в значительной степени эквивалентен и имеет дополнительное преимущество в работе. – dlev

ответ

1

Я думаю, что вы путаете key и T в вашем методе. Я хотел бы написать это так:

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!"); 
    } 
} 

вы получите лучшее понимание того, как машинопись работает с помощью playground. Вы можете увидеть, как ваш код компилируется:

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' 

Там нет в составленном JS нет T. Он будет отображаться только в вашем TypeScript, предварительно скомпилированном.

Кроме того, вы не можете позвонить:

getValue<VALUE>(...) 
Смежные вопросы