首页 > 解决方案 > 交叉点“...”减少为从不

问题描述

我从 API 接收到一个事件,该事件具有分配给它的事件类型。对于每种类型的事件都有不同的模式,所以我为每个事件创建了一个单独的类型。问题是,Typescript 将事件的交集减少到never,因为每种事件类型的属性type都不同。我应该怎么做才能避免这个错误?

这是一个简化的代码:

type EventType = 'login' | 'newMessage';

type ExampleEvent = {
  type: EventType;
  payload: unknown;
};

type LoginEvent = ExampleEvent & {
  type: 'login';
  payload: {
    userId: string;
  };
};

type NewMessageEvent = ExampleEvent & {
  type: 'newMessage';
  payload: {
    messageId: string;
  };
};

const loginEvent = {
  type: 'login',
  payload: {
    userId: 'abc',
  },
};

const newMessageEvent = {
  type: 'newMessage',
  payload: {
    messageId: 'abc',
  },
};

const events = [loginEvent, newMessageEvent];

const handlers = {
  login: (event: LoginEvent) =>
    console.log('user logged in', event.payload.userId),
  newMessage: (event: NewMessageEvent) =>
    console.log('new message', event.payload.messageId),
};

events.forEach(event => {
  // Argument of type '{ type: string; payload: { userId: string; }; } | { type: string; payload: { messageId: string; }; }' is not assignable to parameter of type 'never'.
  // The intersection '...' was reduced to 'never' because property 'type' has conflicting types in some constituents.
  // Type '{ type: string; payload: { userId: string; }; }' is not assignable to type 'never'.
  handlers[event.type as EventType](event);
});

标签: typescript

解决方案


由于您使用交集创建事件类型,因此您的处理程序定义的左侧可以是任何相交的东西,ExampleEvent因此您需要像这样定义您的处理程序类型:

const handlers: {
  [K in EventType] : (event: ExampleEvent & any) => void
} = {
  login: (event: LoginEvent) =>
    console.log('user logged in', event.payload.userId),
  newMessage: (event: NewMessageEvent) =>
    console.log('new message', event.payload.messageId),
};

使event接受类型LoginEventNewMessageEvent

操场


推荐阅读