Reproducible example here
My need is: the contentType parameter should accept any class object extended from Content (PublicContent, AdminContent, PrivateContent, etc) and I want to call a static method from this parameter type inside the execute method.
I have a method with the following signature:
async execute<U extends ContentProps>(input: {
contentType: typeof Content;
contentPropsType: typeof ContentProps;
}): Promise<Result<U, Failure>>;
and a class hierarchy as follows:
// 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
}
The issue is that when I call the execute method passing PublicContent as the contentType parameter I'm getting an error saying
Type 'typeof PublicContent' is not assignable to type 'typeof Content'
The method call is:
const result = await this.getContent.execute({
contentType: PublicContent,
contentPropsType: PublicContentProps,
});
My question is: Why I'm getting this error since PublicContent is extending Content?
EDIT: as requested by @Chase, the full types for Entity and 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;
}
}