省略具有通用类型的 class 的属性

Omit properties of a class with generic type

我正在研究 Typescript entities library (encoding/decoding JSON <=> 类).

我正在尝试正确进行类型检查,并且我在我的 Entity class 上成功实现了它,但我无法在我的 EntityBuilder class.

原因是 Entity 适用于 class 个实例,但 EntityBuilder 适用于 class 个实例。

这是一个代码示例 (Typescript playground):

class A {
    x: number;
    z: number;
}

export class EntityBuilder {
    /**
     * Build an entity object from source data.
     */
    public static buildOne<T extends any>(buildClass: T, sourceData: Omit<T, 'fromJson'|'toJson'>): T {
        this.checkClassValidity(buildClass);

        const entity: any = new buildClass();

        if (buildClass.constructor === Array.constructor) console.log(sourceData)

        // we ensure that `fromJson` is available as this
        // could simply be annotated with `@Type(Object)`
        if (typeof entity.fromJson === 'function') {
          entity.fromJson(sourceData);
          return entity;
        } else {
          return sourceData as T // don't mind me
        }
    }

    /**
     * Build multiple entities from an array of source data.
     */
    public static buildMany<T>(buildClass: T, sourceData: Omit<T, 'fromJson'|'toJson'>[]): T[] {
        this.checkClassValidity(buildClass);

        return sourceData.map(entityData => this.buildOne<T>(buildClass, entityData));
    }

    /**
     * Check if a valid class was passed through.
     */
    private static checkClassValidity(buildClass: any) {
        if (typeof buildClass !== 'function') {
            throw new Error('Class could not be found');
        }
    }
}

EntityBuilder.buildOne(A, {})

最后一行returns出现如下错误:

Argument of type '{}' is not assignable to parameter of type 'Pick<typeof A, "prototype">'.
  Property 'prototype' is missing in type '{}' but required in type 'Pick<typeof A, "prototype">'.

虽然我希望它告诉我第二个参数缺少 xz 属性。

我省略了 fromJsontoJson,因为这些是我的 Entity class 中的方法,应该用作 class 用于 class A 的方法(不包括一个简单的代码示例)。

我真的可以帮上忙,我整个下午都在处理它,我想我几乎检查了每个 SO 和 Github 线程。

提前致谢。

您需要将第一个参数(创建 T 的实例)与第二个参数(T 的类型)区分开来。

ppublic static buildOne<T>(buildClass: new () => T, sourceData: Omit<T, 'fromJson'|'toJson'>): T

这告诉 typescript 你想用 new 运算符调用 buildClass 并且 return 是 T 的一个实例,因为 buildClass 本身不是T.

的实例
EntityBuilder.buildOne<A>(A, {})

您现在应该收到错误消息,如您所料,您正在传递的空对象丢失 xz

作为旁注,我不确定将 sourceData 键入为 T 的实例是否有意义,考虑到要创建 [=12] 的实例=].您还可以 T 扩展一些东西,例如,有一个 fromJson 方法而不是 any.