Quality
可能有好有坏,具体取决于类型。这里打字卫士工作正常
enum GoodBad {
Good = 'Good',
Bad = 'Bad'
}
interface IQuality {
readonly type: GoodBad;
}
interface GoodQuality extends IQuality {
readonly type: GoodBad.Good;
}
interface BadQuality extends IQuality {
readonly type: GoodBad.Bad;
}
type Quality = GoodQuality | BadQuality;
let quality: Quality;
if (quality.type == GoodBad.Good) {
let goodQuality: GoodQuality = quality; // No Problem. Working good.
let badQuality: BadQuality = quality; // Throw error. Working good.
}
但现在当我在Product
中包装质量时
interface IProduct {
readonly quality: Quality;
}
interface GoodProduct extends IProduct {
readonly quality: GoodQuality;
}
interface BadProduct extends IProduct {
readonly quality: BadQuality;
}
type Product = GoodProduct | BadProduct;
let product: Product;
if (product.quality.type == GoodBad.Good) {
let goodProduct: GoodProduct = product; // Throw error. Working Bad.
// let badProduct: BadProduct = product; // Throw error. Working fine.
}
防护罩不能按预期工作。
if
阻止和前一个if
阻止的差异是什么? let goodProduct: GoodProduct = product;
为什么会抛出错误?readonly type: GoodBad
上创建另一个IProduct
。但这是额外的,可以消除吗?答案 0 :(得分:2)
类型后卫会影响quality
字段,而不会影响product
变量。类型保护仅影响拥有区分字段的字段;它不会影响所有者。
这样可行:
type Product = GoodProduct | BadProduct;
let product!: Product;
if (product.quality.type == GoodBad.Good) {
let goodQuality: GoodQuality = product.quality; // Ok
let badQuality: BadQuality = product.quality; // Err
let goodProduct: GoodProduct = product; // Err, product not affected
let badProduct: BadProduct = product; // Err, product not affected
}
您添加额外字段的解决方案是好的,另一个是创建自定义类型保护:
function isGoodProduct(p: Product) : p is GoodProduct {
return p.quality.type === GoodBad.Good
}
if (isGoodProduct(product)) {
let goodProduct: GoodProduct = product; // OK
let badProduct: BadProduct = product; // Err
}