网站搜索

typescript - 具有公共属性的对象的判别联合


背景

我定义了一个类型 Payload 如下:

type Payload =
  | {
      category: Category.ROUTE_POINT;
      id: string;
      newValues: Partial<RoutePoint>;
    }
  | {
      category: Category.UNASSIGNED_ROUTE_POINT;
      id: string;
      newValues: Partial<UnassignedRoutePoint>;
    };

我还有一个名为 ArrayUtils.updateObject 的函数,定义如下:

export default class ArrayUtils {
static updateObject = <T>(oldObject: T, newValues: Partial<T>) => 
{
  // code omitted
}

问题

我有一个 reducer,它接收一个包含类型为 Payload 的 payload 的 action 对象。我根据对 category 的检查来缩小 payload 的类型,但不知为何,我的编译器在把 action.payload.newValues 传给 ArrayUtils.updateObject 函数时出现问题,因为它不确定 action.payload.newValues 是否是 Partial<RoutePoint> 类型。

如果我把 action.payload.newValues 赋值给其他变量,编译器就不会有问题。

为什么我的编译器没有意识到已经发生了类型缩小,以信任我的 action.payload.newValues 是正确的类型?

if (action.payload.category !== Category.ROUTE_POINT) return routes;

// action.payload.newValues is already narrowed
// Hovering over action.payload.newValues shows it is of type Partial<RoutePoint>
const newValues = action.payload.newValues; 
return routes.map((route) => {
  return {
    ...route,
    points: ArrayUtils.updateItemInArray(
      route.points,
      action.payload.id,
      (p) => {
        // return ArrayUtils.updateObject(p, action.payload.newValues); does not work
        return ArrayUtils.updateObject(p, newValues); // this works
      }
    ),
  };
});