Невозможно вернуть литерал объекта, потому что ноль или неопределенный - Поток - PullRequest
0 голосов
/ 14 марта 2019

Смешивание типов mayBe с дополнительными опорами литерала объекта

 type Response = {
        data?: string;
    }

 function length(): ?string {
      return undefined;
 }

 function test(): Response {
    const data = length()
    return {
        data
    }
 }

12:         data        ^ Cannot return object literal because null or undefined [1] is incompatible with string [2] in property `data`.
References:
5: function length(): ?string {
                      ^ [1]
2:     data?: string;
              ^ [2]

Поток тестирования

В соответствии с документацией потока для Типы MayBe и Типы объектов Я не уверен, почему я получаю ошибку, есть ли способ исправить это?

1 Ответ

1 голос
/ 16 марта 2019

Возможно, типы и необязательные свойства объекта не совсем одно и то же в потоке, и они не всегда совместимы.

Сначала давайте посмотрим на ссылку на ваш документ для Может быть, Типы :

Возможно, типы принимают указанный тип, а также null или undefined.Так что ?number будет означать number, null или undefined.

Так что ?number в основном number | null | undefined.

Теперь давайте посмотрим на ваш объектТипы link из документов :

В дополнение к типу заданного значения, эти необязательные свойства могут быть либо void, либо вообще отсутствовать.Однако они не могут быть null.

Так что, если мы сделаем type Response { data?: string }, тогда response.data будет в основном string | void.Обратите внимание, что void - это совершенно отдельный тип от null.

Итак, давайте разберем ваш пример:

type Response = {
  data?: string; // void | string
}

function length(): ?string { // void | string | null
  return undefined;
}

function test(): Response {
  const data = length()
  // at this point, as far as flow knows, `data` can be `void`, `string`, or
  // `null`, and we're trying to set it as the `data` property on our
  // `Response` type which expects a `void` or a `string`, and does not
  // expect a `null`.
  return {
    data
  }
}

Итак, в основном, Response.data ожидает void | string ивы пытаетесь установить его с void | string | null.Тип должен где-то измениться, чтобы вы могли успешно завершить операцию.Существует несколько возможных подходов:

Вариант один , измените length возвращаемое значение, чтобы быть более конкретным.Вероятно, самое простое:

function length(): void | string {
  return undefined;
}

Мы исключили возможность data, являющуюся null, поэтому больше нет ошибки типа.

Второй вариант , makeResponse.data может быть, типа

Если они оба, может быть, типа, проблема исчезнет.Наименьшее возможное изменение будет следующим:

type Response = {
    data?: string | null;
}

Мы только что добавили возможность Response.data, равную null.Теперь он может принимать тип возврата length, совпадение типов, без ошибок.Но это немного сбивает с толку, комбинируя null с необязательным свойством.Вместо этого мы могли бы сделать это:

type Response = {
    data: ?string,
}

Вариант три , уточните тип:

function test(): Response {
  const data = length()
  // at this point response.data is `void`
  const response = {};
  if (data) {
    // data is now a `number`, not `number | void | null`
    response.data = data;
  }
  // response.data is now `number | void` (not `null`)

  return response
}

Решение о том, какой из этих вариантов использовать, почти полностью зависито лучшем API для любой имеющейся проблемы, а также, возможно, стилистическом выборе того, как подходить к необязательным или типам вообще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...