【发布时间】:2021-05-15 11:58:54
【问题描述】:
可复现的例子here
我的需要是:contentType 参数应该接受从 Content 扩展的任何类对象(PublicContent、AdminContent、PrivateContent 等),并且我想在 execute 方法内从该参数类型调用静态方法。
我有一个带有以下签名的方法:
async execute<U extends ContentProps>(input: {
contentType: typeof Content;
contentPropsType: typeof ContentProps;
}): Promise<Result<U, Failure>>;
类层次结构如下:
// content.entity.ts
export class ContentProps extends EntityProps {}
export class Content<T extends ContentProps> extends Entity<T> {
public constructor(props: T) {
super(props);
}
}
// public-content.entity.ts
export class PublicContentProps extends ContentProps {
readonly title: string;
readonly text: string;
}
export class PublicContent extends Content<PublicContentProps> {
constructor(props: PublicContentProps) {
super(props);
}
// ommited
}
问题是,当我调用 execute 方法并将 PublicContent 作为 contentType 参数传递时,我收到一条错误消息
类型“typeof PublicContent”不可分配给类型“typeof Content”
方法调用为:
const result = await this.getContent.execute({
contentType: PublicContent,
contentPropsType: PublicContentProps,
});
我的问题是:为什么我收到此错误,因为 PublicContent 正在扩展 Content?
编辑:应@Chase 的要求,Entity 和 EntityProps 的完整类型:
// entity.ts
export abstract class EntityProps extends BaseEntityProps {
id?: string;
createdAt?: Date;
updatedAt?: Date;
}
export abstract class Entity<T extends EntityProps> extends BaseEntity<T> {
get id(): string {
return this.props.id;
}
get createdAt(): Date {
return this.props.createdAt;
}
get updatedAt(): Date {
return this.props.updatedAt;
}
protected constructor(entityProps: T) {
super(entityProps);
}
}
// base.entity.ts
export abstract class BaseEntityProps {}
export abstract class BaseEntity<T extends BaseEntityProps> extends Equatable {
protected readonly props: T;
protected constructor(baseEntityProps: T) {
super();
this.props = baseEntityProps;
}
static create<T = BaseEntity<BaseEntityProps>, U = BaseEntityProps>(
this: {
new (entityProps: U): T;
},
propsType: { new (): U },
props: U,
): Result<T, ValidationFailure> {
const violations = validateSchemaSync(propsType, props);
return violations?.length
? Result.fail(new ValidationFailure(violations))
: Result.ok(new this({ ...props }));
}
toJSON(): T {
return this.props;
}
}
【问题讨论】:
-
为什么是
typeof?typeof Content为您提供类对象的类型(静态端),而Content是实例端类型。所以应该不兼容。如果要引用实例端(从类实例化的对象)- 删除typeofs -
@Chase 这是因为我在
execute方法中使用了来自*Content的static方法。基本上,我的需要是:contentType参数应该接受从Content扩展的任何类对象(PublicContent、AdminContent、PrivateContent等) -
啊,我明白了。您可以发布
EntityProps和Entity的完整类型吗?以及完整的错误——通常错误会抱怨特定的不兼容——在这种情况下,它应该告诉你一些类似于“构造函数签名不兼容”的内容 -
请考虑修改您的示例代码以构成一个适合放入独立 IDE 的 minimal reproducible example,例如 The TypeScript Playground,它展示了您所面临的问题,并且仅展示了您所面临的问题。理想情况下,这意味着您将删除与问题无关的任何内容。这样一来,想要帮助您解决问题的人就可以着手解决问题,而无需首先努力解决问题……并且增加了答案适用的机会。
-
嗨@jcalz 感谢您的评论。 Here 一个可重现的例子。感谢您的帮助!
标签: javascript typescript inheritance typeof