确保我的函数 returns 突变对象与 instanceof 相同 class 打字稿?

Ensure my function returns mutated object as instanceof the same class typescript?

export const FilterUndefined = <T extends object>(obj: T): T => {
  return Object.entries(obj).reduce((acc, [key, value]) => {
    return value ? { ...acc, [key]: value } : acc;
  }, {}) as T;
};

我正在迁移数据库和清理旧数据结构的一部分,一些键的一些值最终变成了文字 undefined。该密钥将仍然存在,并将具有值 undefined

我做了这个函数,但是用它修改了一个 class 对象后,它将不再是同一个 class 的实例。我怎样才能使这个 return 成为与输入参数具有相同 class 实例的对象?

as T 让 TS 编译器闭嘴,仅此而已。

我还尝试获取该对象的原型,并且 return new prototype(obj)return new prototype.constructor(obj)

原型的控制台日志如下所示:

PROTOTYPE TestClass {}

我正在使用此设置进行测试:

  it('should return the same type that it receives', () => {
    class TestClass {
      name: string;
      optionalProperty?: any;
    }

    let testObject = new TestClass();
    testObject.name = 'My Name';
    testObject.optionalProperty = undefined;

    console.log(testObject instanceof TestClass);
    testObject = FilterUndefined(testObject);

    console.log(testObject instanceof TestClass);
    console.log(testObject);

    expect(testObject).instanceOf(TestClass);
  });

编辑:JSFiddle:https://jsfiddle.net/3sdg98xt/2/ 但是从 vscode 复制粘贴没有任何问题 运行 我收到一个错误 'execpted expression, got ';'

此解决方案将通过删除具有未定义值的键来改变输入对象。

function removeUndefined <T>(object: T): T {
    for (const id in object) {
       if (object[id] === undefined) {
          delete object[id];
       }
    }
    return object;
}

它似乎适用于您的测试用例:Test in typescript playground

是的,reduce 的每次迭代都会 return 创建一个新的 {},它是一个实例 Object

因此,要使 return 对象与参数的实例相同,您应该进行以下更改。

export const FilterUndefined = (obj) => {
return Object.entries(obj).reduce((acc, [key, value]) => {
    if (value) {acc[key] = value;}
    else {delete acc[key]}
    return  acc;
  }, new obj.constructor);
};

或者您可以根据您正在使用的 typescript 输出的 target 使用 new obj.__proto__.constructor

如果您对此代码段有打字稿问题,请回复。