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

TypeScript中为set函数关联自定义设置类型的技术咨询

问题解答

1. 额外类型信息的定义位置

你需要为每个实体(Player、Team)单独定义可更新字段的约束类型,并通过泛型关联到包装类型上,让set函数能根据传入的包装对象推导出对应的合法更新值类型。

具体实现方式:

  • 先给每个实体明确可更新规则:
    // Player的更新规则:要么只传id,要么同时传name+age
    type UpdatablePlayer = { id: string } | { name: string; age: number };
    // Team的更新规则:仅允许更新name/color字段
    type UpdatableTeam = Pick<Team, 'name' | 'color'>;
    
  • 建立实体类型到可更新类型的映射,或者用条件类型做推导:
    // 类型映射表,关联原实体和对应的可更新规则
    type UpdatableMap = {
      Player: UpdatablePlayer;
      Team: UpdatableTeam;
    };
    
    // 或者用条件类型自动匹配
    type GetUpdatable<T> = 
      T extends Player ? UpdatablePlayer :
      T extends Team ? UpdatableTeam :
      T; // 其他类型默认使用原类型结构
    
  • 最后在set函数中通过这个映射约束参数类型:
    function set<T>(
      propOrObject: MyObjectWrapper<T> | MyPrimitiveWrapper<T>,
      newValueToSet: GetUpdatable<T>
    ): T {
      return {} as T;
    }
    

2. 当前结构是否支持实现需求

当前的包装结构可以支持,但需要做针对性扩展:

  • 核心是通过类型映射或条件类型,把MyObjectWrapper<T>和对应的可更新规则绑定,让TypeScript能根据传入的包装对象(比如theTeam属于MyObjectWrapper<Team>),自动推导出newValueToSet必须符合UpdatableTeam的规则。
  • 如果需要支持嵌套对象(比如Team里的player1)的细粒度更新规则,还可以进一步扩展MyPrimitiveWrapper的泛型参数,关联到对应属性的更新约束。

3. 当前实现的不良实践

  • 滥用any类型:set函数的newValueToSet用any完全废弃了TypeScript的类型校验能力,这是最核心的问题。
  • 宽泛的原始类型判断:MyObjectWrapper中用T[P] extends string | number | boolean | any[]判断原始类型,any[]会匹配所有数组(包括对象数组),可能导致本该被包装成MyObjectWrapper的嵌套对象被错误处理成MyPrimitiveWrapper。
  • 无意义的硬断言:get和set函数里的return {} as T属于强制类型断言,完全忽略了返回值和类型T的实际差异,容易引发运行时错误。
  • 包装类型未关联更新规则:当前的MyObjectWrapper只是简单包装原类型的所有字段,没有绑定任何更新约束,导致set函数无法利用包装对象的类型信息做校验。
  • 缺失嵌套对象的更新支持:现有结构没有考虑嵌套层级(比如Team下的Player)的更新规则,无法对这类场景做类型约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:17:33