Typescript рассматривает логическое значение как истинное | ложь, когда функция strictNullCheck выключена - PullRequest
0 голосов
/ 20 февраля 2020

У меня следующий код машинописи:

type PossiblePromise<T> = T extends Promise<infer U>
  ? T | U
  : T | Promise<T>;
type Z = PossiblePromise<boolean>;

const a = "a"
const f: () => Z = () => Promise.resolve(!!a);

Если для strictNullChecks установлено значение false.

Полученный тип Z равен boolean | Promise<false> | Promise<true>, но я ожидаю его быть boolean | Promise<boolean>. Итак, последняя строка выдает ошибку:

Type 'Promise<boolean>' is not assignable to type 'boolean | Promise<false> | Promise<true>'.
  Type 'Promise<boolean>' is not assignable to type 'Promise<false>'.
    Type 'boolean' is not assignable to type 'false'.(2322)
input.ts(7, 10): The expected type comes from the return type of this signature.

Любые идеи, почему машинопись ведет себя так, трактуя boolean как true | false, что не должно иметь место при отключении strictNullChecks.

Как это можно достичь PossiblePromise<T> тип, который работает с булевыми правильно?

1019 *https://www.typescriptlang.org/play/?strictNullChecks=false&ssl=6&ssc=1&pln=7&pc=47#code / C4TwDgpgBACg9gZwQSwEYBsIwE5wLbIIQA8AKgHxQC8UpUEAHsBAHYAmCsuBRxyLAMwjYoAVXIBYAFBQoAflpQAPmOmyAXIpU58hEhQDc00JCgAtarEQoMWbnuKo4cTAEMW5I1OkBjOCwRgKFdLACJXUN9-QKgBTQAKAEpqSgsaJJSuXSIAOmwIBBcANwh4gEIy10SDIA

Ответы [ 2 ]

3 голосов
/ 20 февраля 2020

Вы можете исправить это, подняв тип Promise. Проблема в том, что boolean является типом объединения, а условные типы автоматически распределяются по типам объединения . Рассмотрим следующий код:

type PossiblePromise<T, Y = Promise<T>> = T extends Promise<infer U>
  ? T | U
  : T | Y;
type Z = PossiblePromise<boolean>;

const a = "a"
const f: () => Z = () => Promise.resolve(!!a);

Как вы можете видеть, Y поднимается за пределами типа условия и используется только при необходимости.

Кстати, использование Boolean не является исправлением ваше определение типа, это только другой тип, который хорошо работает с вашей реализацией (Boolean не является типом объединения) - рассмотрим подробнее о Boolean . Это также означает, что, если бы вы использовали любой другой тип объединения, он имел бы такой же неправильный эффект, проверьте ниже разницы

type T = "a" | "b";
// previous result type would be:
type PreviousResult = "a" | "b" | Promise<"a"> | Promise<"b">
// after the change it will be:
type Result = "a" | "b" | Promise<"a" | "b">
1 голос
/ 20 февраля 2020
type Z = PossiblePromise<Boolean>;
...