typescript - 运行时检查开关是否详尽(当编译时详尽时)
问题描述
我有一个switch
涵盖所有编译时间可能性的语句,但是由于该值可以由用户提供,我想在运行时处理意外值。
这似乎是打字稿的类型推断太好的地方,它分配类型never
(因为从编译器的角度来看,这永远不会发生)并且不会让我访问它的任何字段。
简化示例:
type Circle = { shape: "circle", radius: number };
type Rectangle = { shape: "rectangle", length: number, width: number };
function area(shape: Circle | Rectangle): number {
switch (shape.shape) {
case "circle": return Math.PI * shape.radius * shape.radius;
case "rectangle": return shape.length * shape.width;
}
throw new Error(`Unexpected shape '${shape.shape}'`); // Error: Property 'shape' does not exist on type 'never'.
}
有没有一种优雅的方法来修复最后一行?(比转换为any
或使用下标运算符更优雅)。
解决方案
此页面提供了一个解决方案: https ://www.typescriptlang.org/docs/handbook/advanced-types.html
适合您的示例:
type Circle = { shape: "circle", radius: number };
type Rectangle = { shape: "rectangle", length: number, width: number };
function throwOnNever(x: {shape: string}): never {
throw new Error(`Unexpected shape: ${x.shape}`);
}
function area(shape: Circle | Rectangle): number {
switch (shape.shape) {
case "circle": return Math.PI * shape.radius * shape.radius;
case "rectangle": return shape.length * shape.width;
default: return throwOnNever(shape);
}
}
推荐阅读
- python - 如何从张量流中的张量中删除特定值的向量?
- javascript - 隐藏在模态后面的 BsDatePicker
- spring-boot - 如何仅将请求的文件获取到链接实体
- c# - WPF MaterialDesign 对话框宿主
- android - 如何使用 Retrofit 保存和累积请求正文数据?
- java - 在 Java 中将人类可读的时间解析为毫秒
- java - 交换默认图标,就像密码上的gmail一样在TextInputLayout中显示隐藏
- python - 与 asyncio 一起运行阻塞和解除阻塞任务
- java - 检查 jpql 查询中的 java Timestamp 是否为空
- java - 使用不同(但正确)的算法在 Python 中查找 LU 分解时得到不同的结果。两种算法在 Java 中都运行良好