Возможно, типы и необязательные свойства объекта не совсем одно и то же в потоке, и они не всегда совместимы.
Сначала давайте посмотрим на ссылку на ваш документ для Может быть, Типы :
Возможно, типы принимают указанный тип, а также 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 для любой имеющейся проблемы, а также, возможно, стилистическом выборе того, как подходить к необязательным или типам вообще.