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

从泛型对象移除非函数属性并在泛型类中使用的TS问题

问题分析与解决方案

错误原因

你遇到的TS2322错误本质源于两点:

  1. 泛型T没有类型约束,TypeScript认为它可以是任意类型(比如number、string这类基本类型),当block.genericObject为undefined时,展开后的{}无法赋值给非对象类型的T。
  2. block.genericObject的类型是NonFunctionProperties<T>(T的非函数属性子集),而this.genericObject是完整的T类型,TypeScript无法自动识别子集到父集的赋值合法性,加上可选属性的不确定性,导致类型不匹配。

修复方案

步骤1:给泛型T添加对象约束

确保T只能是对象类型,从根源避免基本类型引发的赋值冲突:

export default class Test<T extends object> {
  // ... 其余代码不变
}

步骤2:安全处理可选属性赋值

先判断block.genericObject是否存在,再用类型断言明确子集到父集的赋值合法性,避免空对象触发类型错误:

constructor(block: Test<NonFunctionProperties<T>>) {
  this.typedObject = { ...block.typedObject };
  if (block.genericObject) {
    this.genericObject = block.genericObject as T;
  }
}

完整修复后的代码

/**
获取所有非函数属性名
 */
export type NonFunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];

/**
按名称挑选非函数属性
 */
export type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;

/**
泛型类Test
 */
export default class Test<T extends object> {
  genericObject?: T;
  typedObject: object;

  constructor(block: Test<NonFunctionProperties<T>>) {
    this.typedObject = { ...block.typedObject };
    if (block.genericObject) {
      this.genericObject = block.genericObject as T;
    }
  }
}

/**
使用示例
 */
type CustomType = {
  num: number;
  str: string;
  ignoredFn: () => void;
};

// 直接传入CustomType即可,构造参数会自动处理为非函数属性版本
const myTestObject = new Test<CustomType>({
  genericObject: {
    num: 5,
    str: "string",
  },
  typedObject: {
    num: 5,
    str: "string",
  },
});

额外优化

原使用示例中Test<NonFunctionProperties<CustomType>>可以简化为Test<CustomType>,更贴合你“传入自身无函数版本作为构造参数”的设计意图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:40:45