Структурная типизация ts мешает объединить в один метод несколько объектов
В общем есть класс для проверки Rule.
Необходимо разработать класс OR которая может принять несколько объектов Rule и представляться линтеру как экземпляр Rule.
Упрощенная реализация:
type DomainErr<N extends string> = {
type: 'domain error',
name: N,
}
type Result<F extends DomainErr<string>> = {status: boolean, error: F};
abstract class CheckRule<F extends DomainErr<string>> {
abstract check(params: unknown): Result<F>
}
class OR<F extends DomainErr<string>> implements CheckRule<F> {
private orRules: Array<CheckRule<F>> = [];
private constructor(others: Array<CheckRule<F>>) {
this.orRules = others;
}
static get<E extends DomainErr<string>>(
first: CheckRule<E>,
second: CheckRule<E>,
...others: Array<CheckRule<E>>
): CheckRule<E> {
return new OR([first, second, ...others]);
}
check(params: unknown): Result<F> {
//relase or for rules;
}
}
class Rule1 extends CheckRule<DomainErr<'err1'>> {
check(p: unknown): Result<DomainErr<'err1'>> {
return {status: false, error: {name: 'err1', type: 'domain error'}}
}
}
class Rule2 extends CheckRule<DomainErr<'err2'>> {
check(p: unknown): Result<DomainErr<'err2'>> {
return {status: false, error: {name: 'err2', type: 'domain error'}}
}
}
const rule1 = new Rule1();
const rule2 = new Rule2();
const orRule = OR.get(rule1, rule2); //linter error!!!
//Type '"err2"' is not assignable to type '"err1"'.(2345)
//expected type -> rule: CheckRule<DomainErr<'err1'> | DomainErr<'err2'>>;
const orRule2 = OR.get<DomainErr<'err1'> | DomainErr<'err2'>>(rule1, rule2); //not linter error
//rule2: CheckRule<DomainErr<"err1"> | DomainErr<"err2">>;
Как видно из примера, если линтеру/компилятору не подсказывать ошибки, то он ругается (orRule).
Но если при вызове указать типы ошибок, то все нормально (orRule2).
Насколько я понимаю, проблема в том что ошибки 'err1' и 'err2' имеют разную структуру по полю name и из-за этого линтер ругается.
Что можно сделать чтобы не надо было каждый раз при вызове OR.get() указывать типы ошибок?