typescript - 如何在 TypeScript 中正确使用扩展实例?
问题描述
我使用 TypeScript,但仍然有很多困惑。
我创建了一个这样的实例:
interface Product {
type: 'free'|'pay';
price?: number;
}
我将 price 设置为可选属性的原因是因为我只想在类型为“pay”时才将其设为有效属性。
因此,我想创建一个这样的界面:
interface Product {
type: 'free'|'pay';
}
interface PayProduct extends Product {
type: 'pay';
price: number;
}
我想像这样使用它。
const loggingPrice = (product: Product) => {
if (product.type !== 'pay') return;
// product is definitely PayProduct.
const { price } = product;
console.log(price);
}
但是,当然,它会返回如下错误:
TS2339: Property 'price' does not exist on type 'Product'.
这就是我使用类型断言的原因。
interface Product {
type: 'free'|'pay';
}
interface PayProduct extends Product {
type: 'pay';
price: number;
}
const loggingPrice = (product: Product) => {
if (product.type !== 'pay') return;
// product is definitely PayProduct.
const { price } = product as PayProduct;
console.log(price);
}
我想不出别的办法。
我认为这是一个不好的方法。我真的不喜欢类型断言。(我觉得我在骗输入检查器。)
使用这些定义的接口的最佳方式是什么?
我为我糟糕的英语水平道歉。(我依赖自动翻译。)但是我很好奇是否有办法正确使用这些接口。
解决方案
不要延长。而是创建两种类型的可区分联合。现在它是一个或另一个(不可能只是一个基本接口实例)。测试product.type !== 'pay'
将正确缩小。
见https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions
interface PayProduct {
type: 'pay';
price: number;
}
interface FreeProduct {
type: 'free';
}
type Product = PayProduct | FreeProduct;
const loggingPrice = (product: Product) => {
if (product.type !== 'pay') return;
// product is definitely PayProduct.
const { price } = product;
console.log(price);
}
推荐阅读
- javascript - 如何在不使用 clearRect 的情况下在画布中绘制抗锯齿笔画
- c# - 从一个位置实例化尽可能多的游戏对象并在另一个位置结束
- javascript - 如何在 Ramda 中组成升序/降序排序
- ruby-on-rails - 如何覆盖 Rails 框架中的一种方法?
- r - 针织 pdf 中的图像被切断
- javascript - 为什么这个过渡淡出但不淡入?
- c - 即使按值传递,多维数组值也会被修改
- reactjs - 在生产环境中,如何在开发中使用 localhost 的假后端
- postgresql - PostgreSQL - 仅选择前一个条目满足条件的行
- java - 在 JavaFX 中二次调整网格窗格的大小