Наследование может работать между User
и Participant
классами, если User
является родовым c для указания типа его поля props
.
Другой совет - полагаться на константы ( поддерживает значения, когда они пусты), чтобы получить тип. Это делает код более кратким.
const emptyUserProps = {
firstname: "",
lastname: "",
email: "",
};
export type UserProps = typeof emptyUserProps;
export class User<TProps extends UserProps = UserProps> {
props = emptyUserProps as TProps; // Type assertion `as TProps` is needed here in order to initialise the field using `emptyUserProps` (of type `UserProps`, not `TProps`)
}
// -------
const emptyParticipantProps = {
pseudonym: "",
karma: 0,
impact: 0,
level: 0,
experience: 0,
};
export type ParticipantProps = typeof emptyParticipantProps;
export class Participant extends User<UserProps & ParticipantProps> {
props = {
...emptyUserProps,
...emptyParticipantProps,
};
}
Но если User
и Participant
совместно используют только некоторые данные в поле props
, безопаснее достичь полиморфизма, используя базовый интерфейс, а не наследование классов:
export interface WithProps<TProps> {
props: TProps;
}
// ----
const emptyUserProps = {
firstname: "",
lastname: "",
email: "",
};
export type UserProps = typeof emptyUserProps;
export class User implements WithProps<UserProps> {
props = emptyUserProps;
}
// -------
const emptyParticipantProps = {
pseudonym: "",
karma: 0,
impact: 0,
level: 0,
experience: 0,
};
export type ParticipantProps = typeof emptyParticipantProps;
export class Participant implements WithProps<UserProps & ParticipantProps> {
props = {
...emptyUserProps,
...emptyParticipantProps,
};
}
Другой вариант - использовать один класс generi c с несколькими фабричными методами stati c, один для создания пользователя "basi c", другой для участника:
const emptyUserProps = {
firstname: "",
lastname: "",
email: "",
};
const emptyParticipantProps = {
pseudonym: "",
karma: 0,
impact: 0,
level: 0,
experience: 0,
};
export class User<TProps> {
// `TProps` inferred to `typeof emptyUserProps`
static createUser(props = emptyUserProps) {
return new User(props);
}
// `TProps` inferred to `(typeof emptyUserProps) & (typeof emptyParticipantProps)`
static createParticipant(props = {
...emptyUserProps,
...emptyParticipantProps,
}) {
return new User(props);
}
private constructor(public props: TProps) {}
}