我正在研究Typescript entities library(编码/解码JSON <=>类)。
我正在尝试正确进行类型检查,并在我的Entity
类上成功实现了它,但是在我的EntityBuilder
类上却无法正确实现它。
原因是Entity
适用于类实例,而EntityBuilder
适用于类。
这是一个代码示例(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, {})
最后一行返回以下错误:
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">'.
虽然我希望它能告诉我第二个参数缺少x
和z
属性。
我省略了fromJson
和toJson
,因为这些是我Entity
class中的方法,应作为class A
的父类使用(简单代码中不包含这些方法)例如)。
我真的可以帮上忙,整个下午我都在忙着,我想我已经检查了几乎所有的SO和Github线程。
谢谢。
答案 0 :(得分:1)
您需要区分拳头参数(创建T
的实例)和第二个参数(T
的类型)。
ppublic static buildOne<T>(buildClass: new () => T, sourceData: Omit<T, 'fromJson'|'toJson'>): T
这告诉打字稿您要使用buildClass
运算符调用new
并返回T
的实例,因为buildClass
本身不是{{1的实例}}。
T
您现在应该得到一个错误,即您所传递的空对象丢失了EntityBuilder.buildOne<A>(A, {})
和x
,就像您期望的那样。
作为旁注,我不确定将z
键入为sourceData
的实例是否合理,考虑到重点是创建T
的实例。您还可以让T
扩展某些内容,例如使用T
方法而不是fromJson
。