Как создать файл определения TypeScript для класса, свойства которого изменяются в зависимости от создания экземпляра

Я пытаюсь реализовать файл определения TS DefinitelyTyped для класса JS, который имеет разные определения в зависимости от того, как он создается. Определения четко определены и не изменятся после создания экземпляра.
Пример:

var a = new MyClass("foo");
console.log(a.a);//"a"
console.log(a.b);//"b"
console.log(a.c);//"c"
console.log(a.d);//"undefined"
console.log(a.e);//"undefined"
console.log(a.f);//"undefined"

var b = new MyClass("bar");  
console.log(b.a);//"undefined"
console.log(b.b);//"undefined"
console.log(b.c);//"c"
console.log(b.d);//"d"
console.log(b.e);//"e"
console.log(b.f);//"f"

Я бы хотел, чтобы определение TS выглядело примерно так:

interface myInterface{
    c:string;
}
class MyClass("foo") implements myInterface{
    a:string;
    b:string;
    c:string;
}
class MyClass("bar") implements myInterface{
    c:string;
    d:string;
    e:string;
    f:string;
}

Будем очень признательны за любые указатели
РЕДАКТИРОВАТЬ: Уточнение: я не могу изменить MyClass
Кроме того, существует множество различных способов создания экземпляра MyClass, однако все они хорошо известны и определены заранее. Мы также можем предположить, что нам не нужно беспокоиться о несуществующем варианте MyClass.
Кроме того, MyClass лучше всего описывать как фабрику, которая разрешает доступ к базе данных; поэтому new MyClass("foo") создаст объект, позволяющий получить доступ к таблице foo в базе данных, где имена полей теперь являются свойствами созданного MyClass объекта.


person dainichi    schedule 06.08.2016    source источник
comment
Если они разные, то почему это один и тот же класс? Почему бы не сделать два разных класса?   -  person Alex    schedule 06.08.2016
comment
Синтаксис class MyClass("foo") implements myInterface{ неверен.   -  person    schedule 06.08.2016
comment
Вы ищете вопросительный знак (?), как в d?: string;.   -  person    schedule 06.08.2016
comment
Ваш класс создается только с помощью foo и bar? А если кто-то проедет мимо машины?   -  person YK1    schedule 06.08.2016
comment
@torazaburo Я думаю, что OP ищет способ явно изменить тип класса в зависимости от экземпляра, а не просто сделать все члены необязательными.   -  person Alex    schedule 06.08.2016
comment
@torazaburo, Алекс прав. Я использовал это как пример. Я понимаю, что это неправильно, но показывает конечный эффект, который я ищу. YK1, Можно считать, что это не проблема.   -  person dainichi    schedule 08.08.2016


Ответы (1)


Если у вас есть контроль над кодом...

Вы должны подумать об исправлении этого. То, что вы описываете, - это два разных типа, нет особого смысла в том, чтобы класс менял свой тип в зависимости от входных параметров.

MyClass в вашем примере выглядит как какая-то странная фабрика, которая использует конструктор вместо метода для создания объектов.

Решение в коде может выглядеть примерно так, используя типы объединения и защиту типов:

class Foo {
    public FooMember: string = "I'm foo";
}

class Bar {
    public BarMember:string = "I'm bar";
}

let myObj: Foo | Bar;

myObj = new Foo(); // or FooBarFactory.GetInstance("Foo") or whatever

if(myObj instanceof Foo){
    console.log(myObj.FooMember);
} else {
    console.log(myObj.BarMember);
}

Если у вас нет контроля над кодом...

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

person Alex    schedule 06.08.2016