Как работает тип generi c с extend
, мы ограничиваемся тем, что наш класс, наконец, будет содержать один или несколько возможных членов из BaseActionTypes
. Для типов объединения расширяются средства - все, что присваивается типу, это означает, что он может иметь одинаковое количество вариантов или меньше, но не более того. Вы спрашиваете, как тогда присваивается ваш тип ExtendedActionTypes
, если у него есть еще одна опция ... а на самом деле это не так, это только потому, что вы не заполнили реализацию типов, и все три - это то же самое, что TS структурно типизированный язык. Если вы добавите эти типы и свойства, у вас будет ошибка, проверьте это здесь .
Так что ExtendedActionTypes
нельзя назначить на BaseActionTypes
, потому что у него больше опций, а не меньше.
Ваша ошибка, хотя и имеет другую причину, поскольку вы пытаетесь установить значение типа Walk
в значение, которое ActionTypes extends BaseActionTypes
. И это означает, что ActionTypes
является возможным типом, который не включает Walk
, поэтому вы не можете выполнить такое назначение. Ниже доказательство:
// no error as `Run` extends `BaseActionTypes`
class ExtendedActionDoer extends ActionDoer<Run> {
}
Как видите, Walk
нельзя назначить Run
.
Одним из возможных исправлений проблемы является удаление ограничения из класса вообще:
type ExtendedActionTypes = BaseActionTypes | Jump;
class ActionDoer {
doAction<ActionType extends BaseActionTypes>(a: ActionType) {
}
walk() {
const w: Walk = {type: 'Walk'};
this.doAction(w);
}
}
class ExtendedActionDoer extends ActionDoer {
doAction(a: ExtendedActionTypes) {
}
}
const extendedActionDoer = new ExtendedActionDoer();
const j: Jump = {type: 'Jump'};
extendedActionDoer.doAction(j);
ссылка на игровую площадку
Мы также можем сохранить тип c, но при этом иметь свойства, рассмотрим:
type ExtendedActionTypes = Jump;
class ActionDoer<ActionType> {
doAction(a: ActionType | BaseActionTypes) {
}
walk() {
const w: Walk = {type: 'Walk'};
this.doAction(w);
}
}
class ExtendedActionDoer extends ActionDoer<ExtendedActionTypes> {
doAction(a: ExtendedActionTypes) {
}
}
const extendedActionDoer = new ExtendedActionDoer();
const j: Jump = {type: 'Jump'};
extendedActionDoer.doAction(j);
Ссылка на игровую площадку
Самая важная часть - doAction(a: ActionType | BaseActionTypes)
Я говорю, что бы вы ни дали мне, я возьму, но всегда будут члены BaseActionTypes
.