You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript编译器未对联合类型Partial<A_or_B>的内联声明做类型校验

问题描述

我在reducer模型中定义了一个action,其接收的payload类型结构为{ id: string, newValues: Partial<A_or_B> }。实际开发中发现,当我内联声明newValues时,TypeScript不会对A_or_B的类型约束做校验;但如果我提前声明newValues变量再为其赋值属性,约束就可以正常生效。请问如何配置才能让内联声明的newValues也能正常触发A_or_B的类型约束校验?

问题代码

import { useContext } from "react";
import { AppDispatchContext } from "../src/AppProvider";
import { ActionTypes, A_or_B } from "./interfaces";

export default function App() {
  const dispatch = useContext(AppDispatchContext);

  const x: Partial<A_or_B> = {};
  // 此处会抛出类型错误:Property 'color' does not exist on type
  // 'Partial<A> | Partial<B>'.
  // Property 'color' does not exist on type 'Partial<A>'.
  x.color = "red";

  dispatch({
    type: ActionTypes.POINT_UPDATED,
    // 此处仅内联声明newValues,color仅属于B类型,为什么不会触发类型错误?
    payload: { id: "x", newValues: { color: "red" } }
  });
}

原因说明

这个差异来自TypeScript联合类型的两种校验规则:

  1. 给联合类型赋值对象字面量时,TS只会校验该字面量是否符合联合中任意一个分支的类型要求,只要符合其中一个就判定为合法。你内联写的{color: "red"}符合Partial<B>的要求,所以不会触发报错。
  2. 当你提前声明了类型为Partial<A_or_B>的变量再修改属性时,TS无法确定这个变量当前属于联合的哪个分支,所以只允许操作所有分支共有的属性,因此给x.color赋值会抛出错误。

解决方案

根据你的实际需求选择对应方案:

  • 如果你希望newValues只能传入A和B两种类型的共有属性,直接修改action的payload类型定义,把Partial<A_or_B>替换为Partial<A & B>,这样只要传入任意非共有的属性,不管是内联写法还是提前声明变量,都会触发类型错误。
  • 如果你允许传入单个分支的属性,只是希望内联写法也能提前识别不符合要求的字段:
    1. 给内联的newValues显式标注类型,或者提前声明带类型的newValues变量再传入:
    // 此处会直接抛出类型错误
    const newValues: Partial<A_or_B> = { color: "red" };
    dispatch({
      type: ActionTypes.POINT_UPDATED,
      payload: { id: "x", newValues }
    });
    
    1. 在tsconfig.json中开启更严格的校验配置,提升类型检查的严格度:
    {
      "compilerOptions": {
        "strict": true,
        "exactOptionalPropertyTypes": true,
        "noImplicitAny": true
      }
    }
    

内容的提问来源于stack exchange,提问作者RouteMapper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:09:03