如果我有一个像这样的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链接到代码