且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

对象类型中缺少流属性

更新时间:2022-10-15 23:38:11

首先-我们将简化示例:

type SubType = { dates?: string, location?: string };
type Foo = (arg: SubType) => void;

type SuperType = { dates?: string };
type Bar = (arg: SuperType) => void;

function convert (arg: Foo): Bar {
  return arg;
  //     ^ Cannot return `arg` because property `location` is missing in `SuperType` [1] but exists in `SubType` [2] in the first argument.
}

换句话说,我们仅使用类型转换将Foo转换为Bar:

const anyObj = ({}: any);

((anyObj: Foo): Bar);
//        ^ Cannot cast object literal to `Bar` because property `location` is missing in `SuperType` [1] but exists in `SubType` [2] in the first argument.

或者可以说我们将SuperType转换为SubType

((anyObj: SuperType): SubType);
//        ^ Cannot cast `anyObj` to `SubType` because property `location` is missing in `SuperType` [1] but exists in `SubType` [2].

要将SuperType转换为SubType,我们可以使用$Shape:

复制提供的类型的形状,但将每个字段都标记为可选.

// Correct
((anyObj: SuperType): $Shape<SubType>);

TLDR:

export type SearchContextType = {
  dates: DateRange,
  location: GoogleMapPosition,
  update: ($Shape<{ dates?: DateRange, location?: GoogleMapPosition }>) => void
  //       ^ add `$Shape`
};

更正实施例 >

I have the following Flow Props type for a component:

type Props = {
  // <...>
  update: ({ dates?: DateRange }) => void
};

I also have the following exported type:

export type SearchContextType = {
  // <...>
  update: ({ dates?: DateRange, location?: Location }) => void
};

When I try to pass props to the first component using the second type I get the following error:

Error:(99, 23) Cannot create MyComponent element because property location is missing in object type 1 but exists in object type [2] in the first argument of property update.

I understand the error, but my question is: how can I get around it properly?

Example

First - we will simplify the example:

type SubType = { dates?: string, location?: string };
type Foo = (arg: SubType) => void;

type SuperType = { dates?: string };
type Bar = (arg: SuperType) => void;

function convert (arg: Foo): Bar {
  return arg;
  //     ^ Cannot return `arg` because property `location` is missing in `SuperType` [1] but exists in `SubType` [2] in the first argument.
}

In other word we just use typecasting to convert Foo into Bar:

const anyObj = ({}: any);

((anyObj: Foo): Bar);
//        ^ Cannot cast object literal to `Bar` because property `location` is missing in `SuperType` [1] but exists in `SubType` [2] in the first argument.

Or we can say that we convert SuperType into SubType

((anyObj: SuperType): SubType);
//        ^ Cannot cast `anyObj` to `SubType` because property `location` is missing in `SuperType` [1] but exists in `SubType` [2].

To convert SuperType into SubType we can use $Shape:

Copies the shape of the type supplied, but marks every field optional.

// Correct
((anyObj: SuperType): $Shape<SubType>);

TLDR:

export type SearchContextType = {
  dates: DateRange,
  location: GoogleMapPosition,
  update: ($Shape<{ dates?: DateRange, location?: GoogleMapPosition }>) => void
  //       ^ add `$Shape`
};

Corrected Example