typescript - 如何区分交叉口
问题描述
鉴于这种事件的结合:
type Events =
| { type: 'CREATE'; data: { foo: string } }
| { type: 'READ'; uuid: string }
| { type: 'UPDATE'; data: { foo: string; uuid: string } };
我制作了处理事件的函数,还收集了一张地图:
const processors: Processors<Events> = {
CREATE: (event) => {
console.log(event.data.foo);
},
READ: (event) => {
console.log(event.uuid);
},
UPDATE: (event) => {
console.log(event.data.uuid);
},
}
该Processors<Event>
类型并不复杂并且可以预见地工作:
type Processors<E extends EventObject> =
{ [T in E['type']]: (event: Extract<E, { type: T}>) => void };
尝试使用这些函数处理事件时遇到问题:
function(event: Events) {
const receiver = processors[event.type]; // this produces (event: never) => void
receiver(event);
^^^^^ error
}
接收器的参数类型是intersection
因为它来自类型中的逆变位置Processors<Event>
:
receiver(event:
{ type: 'CREATE'; data: { foo: string } } &
{ type: 'READ'; uuid: string } &
{ type: 'UPDATE'; data: { foo: string; uuid: string } }
);
我假设事件联合不可分配给事件交集。
如果我歧视工会,问题就消失了:
if (event.type === 'CREATE') {
const receiver = processors[event.type]
receiver(event);
}
但这越来越不合理,因为我们知道事件在任何给定时间总是只有一种类型。
没有类型转换是否可以解决问题?就好像您可以将交集转换为并集,区分交集。
function(event: Events) {
const receiver = processors[event.type]; // this produces (event: never) => void
receiver(event);
^^^^^ How to solve the problem without useless and redundant code?
}
解决方案
推荐阅读
- reactjs - 键入时,我的输入字段中的值未正确更改状态?反应挂钩 PUT
- javascript - 错误 TS7053:元素隐式具有“任何”类型,因为“数据”类型的表达式不能用于索引类型“{}”
- coldfusion - 如果令牌过期,则自动刷新令牌
- snowflake-cloud-data-platform - LOAD_HISTORY 视图始终为空
- javascript - JavaScript 中的解构和初始化
- c# - 如何避免在“Plugin.Media”nuget 中调整图像大小?
- javascript - 我的网站轮播/React.js 有问题
- python - Discord bot 不会将我的消息发送到服务器,而是在终端中打印
- python - 如何让我的正则表达式匹配在前瞻后停止?
- c++ - 似乎找不到链接器我在 python.h 下寻找链接对象