#typescript #generics
Вопрос:
У меня есть супер класс, такой как
class SuperClassy {
}
В котором есть много других классов, расширяющих его:
class SubClassy extends SuperClassy {
}
class OtherSubClass extends SuperClassy {
}
и т.д.
У меня есть функции, для которых я хочу указать, что аргумент должен находиться в этой группе производных классов.
Я не хочу создавать тип объединения вручную, я бы предпочел просто объявить, что рассматриваемый аргумент должен наследоваться от СуперКласса.
Что-то вроде:
function doStuff(c: InheritsFrom<SuperClassy>) {
}
таким образом, что это скомпилирует:
doStuff(new SubClassy()) {
}
и этого не будет:
doStuff(4);
— РЕДАКТИРОВАТЬ —
Вот пример, когда простое требование, чтобы параметр был суперклассным, не работает:
class SuperClassy {
id: string;
}
class SubClassy extends SuperClassy {
x: number;
}
class OtherSubClass extends SuperClassy {
y: number;
}
function doStuff(c: (c: SuperClassy) => (d: SuperClassy) => boolean) {
return 'j';
}
doStuff((c: SubClassy) => {
return (k: OtherSubClass) => {
return c.id === k.id;
}
});
Компилятор выдает эту ошибку:
Argument of type '(c: SubClassy) => (k: OtherSubClass) => boolean' is not assignable to parameter of type '(c: SuperClassy) => (d: SuperClassy) => boolean'.
Types of parameters 'c' and 'c' are incompatible.
Property 'x' is missing in type 'SuperClassy' but required in type 'SubClassy'.
Комментарии:
1. Разве ты не можешь просто сделать
function doStuff(c: SuperClassy)
это ?2. Смотрите обновленный вопрос для случая использования, когда это нарушается
3. Тип функции сложнее, чем вы думали. Они контравариантны в своих типах аргументов и ковариантны в своем типе возвращаемых значений. Тебе нужно переосмыслить их. В принципе, функция, в которую вы передали,
doStuff
не является подтипом типа параметра, для которого определенdoStuff
. т. е.(c: SubClassy) => ...
не является подтипом(c: SuperClassy) => ...
, на самом деле все наоборот.
Ответ №1:
Как насчет использования дженериков? (Я добавил значения по умолчанию в определения классов, чтобы подавить ошибки компилятора.
class SuperClassy {
id: string = "id";
}
class SubClassy extends SuperClassy {
x: number = 0;
}
class OtherSubClass extends SuperClassy {
y: number = 0;
}
function doStuff<T extends SuperClassy, U extends SuperClassy>(
c: (c: T) => (d: U) => boolean
) {
return "j";
}
doStuff((c: SubClassy) => {
return (k: OtherSubClass) => {
return c.id === k.id;
};
});