Псевдоним кругового типа TypeScript не вызывает ошибок и вместо этого расширяет типы единиц - PullRequest
3 голосов
/ 16 марта 2019

Трудно объяснить, что я имею в виду. У меня есть тип Eval, который упрощен, чтобы позволить нам сосредоточиться на ошибке. Его первоначальная цель состояла в том, чтобы преобразовать оператор типа и дерево параметров в логическое значение true или false, но я не могу решить проблему, когда нет сообщения об ошибке для circular type alias, но все работает не так, как задумано. Вот ссылка на игровую площадку . Я ожидаю EvalAll, чтобы оценить до [true], но это [boolean]. Почему это так и что я могу сделать, чтобы решить эту проблему, не прибегая к генерации кода и создавая тонны дубликатов EvalAll и Eval?

Код с детской площадки:

type UnionIncludes<TUnion, TValue> = Extract<TUnion, TValue> extends never ? false : true;
type Or<T extends boolean[]>       = UnionIncludes<T[number], true>;

type Condition = boolean | OperatorOr;

interface OperatorOr<TConds extends Condition[] = any> { '__OR__': TConds; }

type Eval<TCond extends Condition> = (
    TCond extends boolean                     ? TCond                   :
    TCond extends OperatorOr<infer TOrParams> ? Or<EvalAll<TOrParams>>  :
    never
);

type EvalAll <TConds extends Condition[]> = { [i in keyof TConds]: TConds[i] extends Condition ? Eval<TConds[i]> : TConds[i]; };
type EvalAll2<TConds extends Condition[]> = { [i in keyof TConds]: TConds[i] extends Condition ? Eval<TConds[i]> : TConds[i]; };

type expected = EvalAll2<[ OperatorOr<[ true, true ]> ]> // [true];
type actual   = EvalAll <[ OperatorOr<[ true, true ]> ]> // [boolean];
...