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

TypeScript中payload设为Partial<UserState>为何未报错?仅校验首个属性

问题:TypeScript中Redux Action Payload含非法属性未触发报错

我在TypeScript里定义UserAction类型时,把payload设为Partial<UserState>,但dispatch操作中传入包含不存在的ffff属性的payload时,TypeScript并未触发报错,而且看起来仅校验了第一个属性loading。正常情况下TS应该对此类非法属性报错,我检查了Redux的ThunkAction类型未发现问题,有没有人遇到过类似情况?

代码示例

type UserState = {
  user: User | null;
  loading: boolean;
  error: Error | null
}

type UserAction = {
  type: typeof SET_USER;
  payload: Partial<UserState>;
};

type ActionUser = SetDetailedUserAction;

const fetchUser =
  (
    id: string,
  ): ThunkAction<
    Promise<any>,
    RootState,
    any,
    ActionUser
  > =>
  async (dispatch) => {
    
dispatch({
      type: SET_USER,
      payload: { loading: true, ffff: false }, /// 此处`ffff`未触发TS报错
    });
}
可能的原因及解决方法
  • 类型别名定义错误:代码里ActionUser被赋值为SetDetailedUserAction,但未给出该类型的定义。如果SetDetailedUserAction是一个宽松类型(比如允许任意属性),那么ThunkAction的Action参数就不是你预期的UserAction,自然不会校验非法属性。先将ActionUser替换为UserAction,测试是否触发报错。

  • TypeScript结构类型的兼容性特性:TS采用结构类型系统,当传入的对象同时包含合法属性和额外属性时,若目标类型(Partial<UserState>)未明确禁止额外属性,TS可能不会报错。可以通过以下方式强制校验:

    • 对payload进行类型断言,明确指定为UserAction['payload']:
      dispatch({
        type: SET_USER,
        payload: { loading: true, ffff: false } as UserAction['payload'], // 此时会触发非法属性报错
      });
      
    • 定义更严格的payload类型,比如自定义Exact类型来禁止额外属性:
      type Exact<T, U> = T & Record<Exclude<keyof U, keyof T>, never>;
      type StrictUserPayload = Exact<Partial<UserState>, Partial<UserState>>;
      
  • ThunkAction泛型参数不匹配:ThunkAction的第四个泛型参数指定的是允许dispatch的Action类型,如果ActionUser不是准确的UserAction,dispatch就不会按照UserAction的规则校验。直接将该参数替换为UserAction,确认是否解决问题。

  • 未启用严格类型检查:检查tsconfig.json是否开启了strict: true配置。若严格模式未启用,TS的类型校验会大幅放宽,可能忽略这类非法属性问题。开启严格模式后,TS会更严格地校验类型兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:01:27