我正在为一个项目使用TypeScript,我正在做错误处理,但我观察到TS的一些行为,使我的系统对错误类型不那么严格:
class A extends Error {}
class B extends Error {}
// I can do this
const err: A = new B();
我更喜欢它抛出错误,因为它们不是同一个类,但它工作得很好,从而放松了我的错误类型限制。有谁知道我怎样才能使用B构造函数定义A对象变得不可能吗?
对于您的信息,我想使这成为可能,因为我使用函数式错误处理库,我在方法的定义中定义了它可能抛出的错误,但是当错误类型不够严格时,它会导致问题
我认为这可能是因为A和B对它们的属性有相同的定义,尽管它们是不同的类,我试过在它们中设置不同的属性,但没有成功。
你可以这样做,因为TypeScript的类型系统是结构的(基于类型的形状),而不是名义的(基于类型的名称/标识)。A
和B
都创建具有相同属性集的实例,因此它们是赋值兼容的。
你可以用"branding"-给每个Error
子类一个独特的属性值:
class A extends Error {
readonly type = "A";
}
class B extends Error {
readonly type = "B";
}
// Error here as desired
const err: A = new B();
// ^Type 'B' is not assignable to type 'A'.
// Types of property 'type' are incompatible.
// Type '"B"' is not assignable to type '"A"'. (2322)
操场例子
在你的评论中问:
你认为用这种方法可以做错误继承吗?因为这意味着子元素必须重写父元素的属性,但这意味着如果我不需要子元素级别的精度,我就不能只指定父元素。
是的,您可以通过使用不同的标记属性而不是单个type
属性来做到这一点:
class A extends Error {
readonly __A__ = "A";
}
class B extends Error {
readonly __B__ = "B";
}
class C extends B { // <== `C` subclasses `B`
readonly __C__ = "C";
}
// Works (of course)
const errorA: A = new A();
const errorB: B = new B();
const errorC: C = new C();
// Using parent type works with subclass
const errorB2: B = new C();
// (As desired) Using subclass type with parent class doesn't work
const errorC2: C = new B();
// ^Property '__C__' is missing in type 'B' but required in type 'C'. (2741)
操场上联系