我正在编写一些单元测试,我想测试我的构造函数是否在运行时因参数无效而失败。如果在 TS 项目中使用无效参数调用构造函数,它会在编译时失败,因此我首先必须将其转换为 any
。
我的类.ts
export default class MyClass {
constructor(public value: 1 | 2 | 3) {
if (!this.value ||
isNaN(this.value) ||
this.value < 1 || this.value > 3 ||
parseInt(this.value) !== this.value) {
throw new Error(`Invalid value: '${this.value}'`);
}
}
}
my-class.test.ts
test('MyClass validates its constructor arguments', () => {
expect(() => new (MyClass as any)()).toThrowErrorMatchingSnapshot();
expect(() => new (MyClass as any)('abc')).toThrowErrorMatchingSnapshot();
expect(() => new (MyClass as any)(null)).toThrowErrorMatchingSnapshot();
// ...
});
我想清理一下,所以我只进行一次转换,方法是设置一个局部变量。
test('MyClass validates its constructor arguments', () => {
// this type declaration isn't right
const MC = MyClass as any as { new: (...args: any[]) => MyClass };
expect(() => new MC()).toThrowErrorMatchingSnapshot();
expect(() => new MC('abc')).toThrowErrorMatchingSnapshot();
expect(() => new MC(null)).toThrowErrorMatchingSnapshot();
// ...
});
我依稀记得我写了一个泛型,它有一个类型参数需要一个类,我认为我就是这样写的——一个对象有一个名为 new
的函数,但我现在不能找到我在网上找到它的地方,我什至不记得我最初是在哪个项目中编写它的。
无论如何,对于这段代码,TypeScript 对我大喊大叫:
Cannot use 'new' with an expression whose type lacks a call or construct signature.ts(2351)
我还尝试将 { new: ... }
更改为 { constructor: ... }
,结果相同。
我可以将 MC
保留为 any
,这适合单元测试,但我想知道将来如何做。
最佳答案
test('MyClass validates its constructor arguments', () => {
type Constructor<T> = new (...args: any[]) => T;
const MC = MyClass as Constructor<MyClass>;
expect(() => new MC()).toThrowErrorMatchingSnapshot();
expect(() => new MC('abc')).toThrowErrorMatchingSnapshot();
expect(() => new MC(null)).toThrowErrorMatchingSnapshot();
// ...
});
也可以内联执行此操作,尽管使用解释变量似乎更清楚。
const MC = MyClass as new (...args: any[]) => MyClass;
关于typescript - 在转换为 TypeScript 中的类型的变量上调用 `new`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56603493/