从TypeScript接口到类构造函数的快捷语法



如果我有一个像这样的TypeScript接口:

interface myInterface {
prop1: string;
prop2: string;
prop3: number;
prop4: boolean;
..
..
..
prop30: string
}

我想创建一个实现myInterface的类,我只知道下面这样做的详细方法:

class MyClass implements myInterface {
prop1;
prop2;
prop3;
prop4;
..
..
prop30;
constructor(data: myInterface) {
this.prop1 = data.prop1;
this.prop2 = data.prop2;
this.prop3 = data.prop3;
this.prop4 = data.prop4;
..
..
this.prop30 = data.prop30;
}
}

有任何方法我可以使这个语法更短或任何更好的方法来实现这样的类从接口?

你可以使用Object.assign()data参数的所有成员一次复制到this,但是TypeScript仍然要求你单独声明字段:

class MyClass implements MyInterface {
prop1!: string;
prop2!: string;
prop3!: number;
prop4!: boolean;
/* ..
..
..*/
prop30!: string;
constructor(data: MyInterface) {
Object.assign(this, data);
}
}

所以这是更好的,但不是很好。

(还要注意,编译器不能验证属性是否被赋值,因此您需要在字段声明中使用确定赋值断言操作符(!)来抑制警告。)


如果您可以定义类工厂函数并使用它来生成超类,则可以省去此麻烦。下面是函数:

function AssignCtor<T extends object>() {
return class {
constructor(t: T) {
Object.assign(this, t)
}
} as { new(t: T): T }
}

AssignCtor<T>的返回值被声明为具有构造签名的类型,该签名接受类型为T的值,并产生类型为T的类实例。这就是你想用MyInterface做的,所以让我们试试:

class MyClass extends AssignCtor<MyInterface>() implements MyInterface {
}

就是这样。让我们确保MyClass的行为符合您的期望:

function tryItOut(data: MyInterface) {
const myClass = new MyClass(data);
myClass.prop1.toUpperCase(); // okay    
}

看起来不错。值myClass被看作具有MyInterface的属性。

Playground链接到代码

相关内容

  • 没有找到相关文章

最新更新