уточнение неизменяемого свойства обнуляемого объекта - PullRequest
1 голос
/ 19 сентября 2019

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

/* @flow */
const a: {+foo: ?string} = {};

const fun = (obj: {+foo: string}) => {
  return obj
}

if (a.foo) {
  fun(a) // null or undefined [1] is incompatible with string
}

Try flow

Он не должен работать с объектом с изменяемым свойством, потому чтоэто свойство может быть изменено на null позже.Вот почему я использую неизменное свойство.Но это все равно не работает.

Есть ли способ передать объект с уточненным свойством?

Ответы [ 2 ]

3 голосов
/ 20 сентября 2019

Уточнение свойства объекта уточняет свойство, а не объект.

// `a.foo` is of type `?string`
// `a` is of type `{+foo: ?string}`
if (a.foo) {
  // within this block, `a.foo` is of type `string` (no `?`)
  // `a` is of type `{+foo: ?string}`
}
// `a.foo` is of type `?string`
// `a` is of type `{+foo: ?string}`

В этом конкретном случае я бы, вероятно, сделал бы что-то вроде этого:

if (a.foo) {
  fun({ foo: a.foo });
}

( Попробуйте )

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

type A = {
  +foo: string,
};

type B = {
  +foo: void,
};

type T = A | B;

const a: T = ({ foo: undefined }: B);

const fun = (obj: A) => {
  return obj
}

// `a` is of type `A | B` (which is type `T`)
if (a.foo) {
  // inside this block `a` is of type `A`
  fun(a);
}
// `a` is of type `A | B` (which is type `T`)

( Try )

В концедень, не существует супер прямого способа конвертировать { +foo: ?string } в { +foo: string }, потому что это два совершенно разных сложных типа, и они должны обрабатываться как таковые.

1 голос
/ 19 сентября 2019

Вы можете попробовать использовать косвенное приведение, где вы приведете тип к any, потому что any принимает любой тип значения в качестве ввода.Тогда, поскольку тип any также позволяет вам читать из него все возможные типы, вы можете присвоить значение any вашему типу, потому что any также ваш тип.

/* @flow */
const a: {+foo: ?string} = {};

const fun = (obj: {+foo: string}) => {
  return obj
}

if (a.foo) {
  fun((a: any))
}
...