我试图理解为什么TS在下面的例子中没有将inst
缩小到Bar
:
class Foo {}
class Bar { prop = "baz" }
function fn2(inst: Foo | Bar) {
if (inst instanceof Foo) {
inst = new Bar()
}
inst.prop // prop does not exist on Foo | Bar
}
我试图理解为什么TS在下面的例子中没有将inst
缩小到Bar
:
class Foo {}
class Bar { prop = "baz" }
function fn2(inst: Foo | Bar) {
if (inst instanceof Foo) {
inst = new Bar()
}
inst.prop // prop does not exist on Foo | Bar
}
Typescript是structural,而不是nominal.这里的问题是,Bar
的一个实例是assignable到Foo
类型,所以类型保护实际上没有缩小任何范围.
class Foo {}
class Bar { prop = "baz" }
const inst: Foo = new Bar() // fine
只有一个属性的对象符合没有属性的对象的接口,因为所有属性(都为零)都被考虑在内.
要实现这一点,需要使这两个类具有不同的接口.
class Foo { foo = 'foo' }
class Bar { bar = 'bar' }
declare let inst: Foo | Bar
if (inst instanceof Foo) inst = new Bar()
inst.bar // works
inst.foo // error
或者在您的具体情况下:
class Foo { foo = 'foo' }
class Bar { bar = 'bar' }
function fn2(inst: Foo | Bar) {
if (inst instanceof Foo) {
inst = new Bar()
}
inst.bar
}