示例代码有两个问题:
你问的关于try 使用C.constructor
的问题
示例用法是try 将ValueObject<number>
视为Example
,但Example
是ValueObject<{value: number;}>
.
请回复您的后续 comments :
从技术上讲,我想避免在每次调用构造函数之前判断是否定义了什么,我不想在每个子类中为它定义特定的函数,所以我希望在抽象上继承它,或者可能在ValueObjectFactory
个类中.但在这两种情况下,我不知道如何准确地定义类型……
当我问独立函数是否适合时,您说它适合,所以:您可以这样定义该函数:
function buildIfDefined<CProps>(
c: new (...args: any[]) => ValueObject<CProps>,
props?: CProps
): ValueObject<CProps> | undefined {
if (props === undefined) {
return undefined;
}
return new c(props);
}
它接受要使用的构造函数和要使用的props ,或undefined
.如果props 为undefined
,则返回undefined
,否则使用props 构造对象并返回.
用途:
function buildExampleIfValueDefined(
props?: { value: number }
): Example | undefined {
return buildIfDefined(Example, props);
}
Playground link个
请注意,它不允许您直接将ValueObject
作为构造函数传递,也不允许将任何其他abstract
类作为构造函数传递,因为构造函数参数的类型签名需要公共构造函数.
回答你原来的问题:
Re#1,C
只是一个类型,而不是错误提到的值.您可以通过根本不try 使用C
来修复该错误,使用this
而不是C.constructor
.在static
方法中,this
是该方法被调用的构造函数(这只是this
的正常行为,它被设置为您对其调用该方法的对象,除非有什么适当的措施来防止这种情况).所以,如果你在通话过程中拨打Example.buildIfDefined
,this
是Example
.
TypeScrip不会喜欢你的ValueObject
类,因为它看起来,就像你试图实例化一个abstract
类.我们可以通过添加我们自己的支票来解决这个问题,然后告诉Tyescript不要担心:
public static buildIfDefined<CProps>(
props?: CProps
): ValueObject<CProps> | undefined {
if (this === ValueObject) {
throw new Error(
"ValueObject.buildIfDefined cannot be called directly, only via a subclass"
);
}
if (props === undefined) {
return undefined;
}
const ctor = this as unknown as (new (props: CProps) => ValueObject<CProps>);
return new ctor(props);
}
用途:
function buildExampleIfValueDefined(
props?: { value: number; }
): Example | undefined {
return Example.buildIfDefined(props);
// ^^^^^
}
Playground link个
这不具有独立函数必须防止abstract
个构造函数的自动处理,所以我们必须使用类型断言来解决这个问题.