Я пытаюсь создать новый объект параметра типа в моем родовом классе. В моем классе View
меня есть 2 списка объектов общего типа, передаваемых в качестве параметров типа, но когда я пытаюсь создать new TGridView()
, TypeScript говорит:
Не удалось найти символ 'TGridView
Это код:
module AppFW {
// Represents a view
export class View<TFormView extends FormView, TGridView extends GridView> {
// The list of forms
public Forms: { [idForm: string]: TFormView; } = {};
// The list of grids
public Grids: { [idForm: string]: TGridView; } = {};
public AddForm(formElement: HTMLFormElement, dataModel: any, submitFunction?: (e: SubmitFormViewEvent) => boolean): FormView {
var newForm: TFormView = new TFormView(formElement, dataModel, submitFunction);
this.Forms[formElement.id] = newForm;
return newForm;
}
public AddGrid(element: HTMLDivElement, gridOptions: any): GridView {
var newGrid: TGridView = new TGridView(element, gridOptions);
this.Grids[element.id] = newGrid;
return newGrid;
}
}
}
Могу ли я создавать объекты из универсального типа?
Поскольку скомпилированный JavaScript имеет всю информацию о типе, вы не можете использовать T
для нового объекта.
Вы можете сделать это не общим способом, передав этот тип в конструктор.
class TestOne {
hi() {
alert('Hi');
}
}
class TestTwo {
constructor(private testType) {
}
getNew() {
return new this.testType();
}
}
var test = new TestTwo(TestOne);
var example = test.getNew();
example.hi();
Вы можете расширить этот пример с помощью дженериков, чтобы затянуть типы:
class TestBase {
hi() {
alert('Hi from base');
}
}
class TestSub extends TestBase {
hi() {
alert('Hi from sub');
}
}
class TestTwo<T extends TestBase> {
constructor(private testType: new () => T) {
}
getNew() : T {
return new this.testType();
}
}
//var test = new TestTwo<TestBase>(TestBase);
var test = new TestTwo<TestSub>(TestSub);
var example = test.getNew();
example.hi();
Чтобы создать новый объект в общем коде, вам нужно обратиться к типу с помощью его функции-конструктора. Поэтому вместо того, чтобы писать это:
function activatorNotWorking<T extends IActivatable>(type: T): T {
return new T(); // compile error could not find symbol T
}
Вам нужно написать следующее:
function activator<T extends IActivatable>(type: { new(): T ;} ): T {
return new type();
}
var classA: ClassA = activator(ClassA);
Смотрите этот вопрос: Общий вывод типа с аргументом класса
Вся информация о типе стирается со стороны JavaScript, поэтому вы не можете создавать новые T так же, как и состояния @Sohnee, но я бы предпочел, чтобы этот параметр был введен в конструктор:
class A {
}
class B<T> {
Prop: T;
constructor(TCreator: { new (): T; }) {
this.Prop = new TCreator();
}
}
var test = new B<A>(A);
export abstract class formBase<T> extends baseClass {
protected item = {} as T;
}
Его объект сможет принимать любой параметр, однако тип T является только ссылкой на машинописный текст и не может быть создан с помощью конструктора. То есть он не будет создавать никаких объектов класса.
T
, поэтому любые методы получения / установки, определенные в T
могут не работать.
Я пытался создать экземпляр generic из базового класса. Ни один из приведенных выше примеров не работал у меня, поскольку для вызова метода factory требовался конкретный тип.
После некоторого исследования на этом и неспособного найти решение в Интернете, я обнаружил, что это работает.
protected activeRow: T = {} as T;
Куски:
activeRow: T = {} <-- activeRow now equals a new object...
...
as T; <-- As the type I specified.
Все вместе
export abstract class GridRowEditDialogBase<T extends DataRow> extends DialogBase{
protected activeRow: T = {} as T;
}
i использую это: let instance = <T>{};
он вообще работает
EDIT 1:
export class EntityCollection<T extends { id: number }>{
mutable: EditableEntity<T>[] = [];
immutable: T[] = [];
edit(index: number) {
this.mutable[index].entity = Object.assign(<T>{}, this.immutable[index]);
}
}
T
, а просто создаст пустой объект, который, как думает TypeScript, будет иметь тип T
Вы можете объяснить свой ответ более подробно.
new()
тоже должен это сделать - или более общий:type: {new(...args : any[]): T ;}
IActivatable
? Я не могу найти это ни в одном документе.