2016-06-09 2 views
3

Я довольно новичок в TypeScript (1.8), и у меня есть небольшая проблема с наследованием и статическими свойствами.Тип: статические свойства и наследование

Пожалуйста, найдите ниже тестового кода я в настоящее время работает:

class A { 
    public static Items = { 
     FOO: 'A' 
    }; 

    public show() { 
     alert(this.constructor.Items.FOO); 
    } 
} 

class B extends A { 
    public static Items = { 
     FOO: 'B' 
    }; 
} 

var a = new A(); 
var b = new B(); 

a.show(); // alert "A" 
b.show(); // alert "B" 

TypeScript Playground link

Этот код работает отлично, и два предупреждения, показаны как ожидалось.

НО машинописи компилятор выдает ошибку: Property "Items" does not exist on type "Function"

Я понимаю, предупреждение и это совершенно верно с точки машинопись зрения, но как я могу добиться того же результата, делая компилятор счастливым? this.Items.FOO явно не работает, и я не нашел эквивалент self или что-то в этом роде ...

Я что-то упустил?

Заранее благодарен!

+1

Обратите внимание, что ваш 'show' метод не будет работать, если вы ввести дополнительный подкласс, который делает * не * имеет статический' 'деталей собственность, например 'class C extends A {}' –

ответ

4

Был такой же вопрос сегодня: Referencing class without name to use different static method in subclasses in TypeScript.

Существует обсуждение/предложение о том, что this.constructor вернет правильный тип здесь: T.constructor should be of type T.

Что касается возможных решений для вас на данный момент:

Без статического вообще:

class A { 
    public show() { 
     alert(this.getItems().FOO); 
    } 

    protected getItems() { 
     return { 
      FOO: 'A' 
     } 
    }; 
} 

class B extends A { 
    protected getItems() { 
     return { 
      FOO: 'B' 
     } 
    } 
} 

(code in playground)

Статика typeof:

class A { 
    public static Items = { 
     FOO: 'A' 
    }; 

    public show() { 
     alert((<typeof A | typeof B> this.constructor).Items.FOO); 
    } 
} 

(code in playground)

Статика конструктор интерфейса:

interface AConstructor { 
    new(): A; 
    Items: any; 
} 

class A { 
    public static Items = { 
     FOO: 'A' 
    }; 

    public show() { 
     alert((this.constructor as AConstructor).Items.FOO); 
    } 
} 

(code in playground)

+0

'alert (( this.constructor) .Items.FOO);' для вашего типа решения, иначе 'B.Items -> B.ItemsRenamed' не будет быть пойманным. –

+0

@mk. спасибо, я обновил свой ответ, хотя считаю, что это решение не очень полезно, когда у вас более двух классов. На мой взгляд, первый вариант (без статического). –

4

Я понимаю, предупреждение и это совершенно верно с точки зрения машинописи

Право - это то, как наследование, но это и не должно вообще работать для статических свойств. Чтобы обойти эту проблему, отключите с помощью any проверки типов:

alert((<any>this.constructor).Items.FOO); 

Такой ситуация часто возникает при преобразовании старого JS кода, но следует избегать при написании нового кода TS. Если вы хотите сделать это правильно, вам понадобится (как вам известно) реализовать и переопределить getItems или аналогичный метод в ваших двух классах, чтобы вернуть соответствующий Items и вызвать этот метод с .

Смежные вопросы