我对打字稿没有太多经验,可以在动态处理对象初始化方面提供一些帮助:
我有一系列的类,它们都具有以下结构的参数子类:
export class MainClass1 {
getParameters(): MainClass1.Parameters | undefined;
setParameters(value?: MainClass1.Parameters): void;
}
export namespace MainClass1 {
export class Parameters{
}
}
export class MainClass2 {
getParameters(): MainClass2.Parameters | undefined;
setParameters(value?: MainClass2.Parameters): void;
}
export namespace MainClass2 {
export class Parameters{
}
}
以上是我正在使用的代码,因此我无法编辑类构造函数,但我需要做的是从字符串开始。例如,“ MainClass1”返回带有实例化MainClass1.Parameters对象的实例化Mainclass1,所以现在我对每个类都有如下代码:
case 'MainClass1':
let mc1 : Lib.MainClass1 = new Lib.MainClass1();
let mc1Params : Lib.MainClass1.Parameters = new Lib.MainClass1.Parameters();
mc1.setParameters(mc1Params);
return mc1;
上面的返回类型是这样的接口:
export interface GenericMainClass {
getParameters() : any;
getId(): string;
setId(value: string): void;
getClassName(): string;
getValue(): Lib.Value | undefined;
setValue(value?: Lib.Value): void;
}
正如我所说,理想情况下,我希望能够动态处理此实例化。谁能告诉我如何从字符串名称中描述如何实例化这些类,这是否可能,然后我应该如何在setParameters周围呈现通用包装,我希望接口上的setParameters<T>(value? : T) : void;
之类的东西可以工作,但打字稿会抱怨当我尝试不兼容的类型时。
任何帮助将不胜感激
答案 0 :(得分:1)
在Typescript中没有100%有效的方法来处理它,但是您可以尝试使用半hacky的方法:
function newClass<TClass extends Lib.GenericMainClass>(name: "Class1" | "Class2"): TClass {
const Class = Lib[name];
const instance = new Lib[name]() as any as TClass;
const parameters = new Lib[name].Parameters();
instance.setParameters(parameters);
return instance;
}
const newInstanceOfClass1 = newClass("Class1");
const newInstanceOfClass2 = newClass("Class2");
const newInstanceOfClass1Typed = newClass<Lib.Class1>("Class1");
const newInstanceOfClass2Typed = newClass<Lib.Class2>("Class2");
这里是TypeScript Playground的网址
说明:
Lib
是这里的一个普通JS对象,您仍然可以引用与普通JS中相同的键。
as any as TClass
是一种hack,可强制TypeScript将未知类型转换为所需类型。
<TClass extends ...>
是泛型类型,在newClass
函数内部使用,可以在调用newClass
函数时定义,如下所示:newClass<MyType>
未定义它:
const newInstanceOfClass1 = newClass("Class1");
它将是Lib.GenericMainClass
的类型
已定义:
const newInstanceOfClass1Typed = newClass<Lib.Class1>("Class1");
它将是Lib.Class1
的类型
因此,如果使用GenericMainClass
时需要newClass
或特定班级,则可以自由选择
注释:
如果要绝对使用类的任何名称,请定义newClass
函数,如下所示:
function newClass<TClass extends Lib.GenericMainClass>(name: string): TClass {
...
如果您仍然希望控制所有可能的类名,则可以使用enum:
enum ClassNames {
Class1: "Class1",
Class2: "Class2",
...
}
function newClass<TClass extends Lib.GenericMainClass>(name: ClassNames): TClass {
...