Можно ли ограничить универсальный c тип T набором подтипов типа K, не включая K? Я пытаюсь определить тип для функций смешивания на основе наследования. Вопрос 32488309 дает ответ для противоположного, и по совпадению этот вопрос задается, но остается без ответа в комментариях.
TypeScript Playground
// Define a type for the constructor signature.
interface IConstructor { new(...args: any[]): any; }
type Mixin = <T extends IConstructor, U extends T>(Base: T) => U;
// Mix a set of mixins.
function mix(...mixins: Mixin[]) {
return mixins.reduce((child: IConstructor, mixer) => mixer(child), Object);
}
// Mix typically accepts Mixins with the same constructor signature.
interface ILocalized extends IConstructor {
new(i18n: I18n): any;
}
function mixinOne(Base: ILocalized) {
return class MixinOne extends Base {
constructor(i18n: I18n) { super(i18n); }
}
}
Это приводит к следующей ошибке из вопрос 56505560 , которая объясняет, что я достиг противоположности моей цели. T не может быть набором подтипов K, потому что, когда он является MixinOne, он не может быть любым другим.
const LocalizedBase: IBase = mix(mixinOne, ...);
'typeof MixinOne' можно назначить ограничению типа 'T', но 'T' может быть создан с другим подтипом ограничения 'IConstructor'.
В качестве альтернативы следующее устраняет ошибку, но включает K, несмотря на использование extends.
export type Mixin = (Base: IConstructor) => IConstructor;
Меня не интересует свойство, повторяющее альтернативное решение для миксинов, потому что эти классы требуют внедрения зависимостей.