31

I'm writing a small React Native app and I'm trying to use Flow, but I can't really get a proper tutorial about it anywhere.

I keep getting the error: destructuring (Missing annotation) about the ({ station }) in the 1st line of this code:

const StationDetail = ({ station }) => {
  const {
    code,
    label,
  } = station;

station is a json response and code and label are strings inside that json.

How do I fix the error/warning?

Nat Mote
  • 3,878
  • 13
  • 28
jbssm
  • 5,976
  • 10
  • 45
  • 76
  • If station is a JSON response, maybe you must write `{'code': code, 'label': label}` no ? – BNilsou Jan 03 '17 at 12:12
  • With `flow` I don't know, but in plain JS React Native is fine that way. – jbssm Jan 03 '17 at 12:17
  • It is because of the scope of ES6 type annotations restriction. You can just specify the type of the const just like `...const {code:string, label:string}...` – Neel Gala Jan 03 '17 at 12:19

3 Answers3

48

I would write this as

type StationType = {
  code: String,
  label: String,
}

function StationDetail({ station } : {station : StationType}) => {
  const {
    code,
    label,
} = station;

It's necessary to declare the type of the object parameter that the function accepts.

John
  • 1,160
  • 12
  • 23
9

I tried your example and got No errors!, because Flow doesn't require type annotations on private functions.

If instead I add an export like this:

// @flow
export const StationDetail = ({ station }) => {
  const {
    code,
    label,
  } = station;
  return code + label;
};

I get the following error. (Which I assume is close enough to what you are seeing.)

Error: 41443242.js:2
  2: export const StationDetail = ({ station }) => {
                                   ^^^^^^^^^^^ destructuring. Missing annotation


Found 1 error

You can solve that in at least two ways. The better way is to add a type annotation for the function argument. For example:

export const StationDetail =
  ({ station }: { station: { code: number, label: string } }) =>

or

export const StationDetail =
  ({ station }: {| station: {| code: string, label: string |} |}) =>

or even

type Code = 1 | 2 | 3 | 4 | 5 | 6;
type Radio ={|
  station: {| code: Code, label: string |},
  signalStrength: number,
  volume: number,
  isMuted: bool,
|};
export const StationDetail = ({ station }: Radio) =>
  ...

if you want to make sure the StationDetail is always called with a proper Radio object even though the current implementation only looks at the station field.

The other alternative is to change the first comment to // @flow weak and let Flow infer the argument type on it's own. That is Less Good™ because it makes it easier to accidentally change your public API and makes your actual intentions less clear.

aij
  • 4,278
  • 28
  • 38
0

In order the object destructuring work you should provide the appropriate object structures on the right side of the assignment. In this particular case {station} as the function argument (left side of the assignment) should be fed by something like {station:{code: "stg", label:"stg"}}. Make sure you are calling the StationDetail function with an appropriate object as argument like.

var StationDetail = ({ station }) => {
  var {code, label} = station;
  console.log(code,label);
},
    data = {station: {code: 10, label:"name"}};

StationDetail(data);
Redu
  • 19,106
  • 4
  • 44
  • 59
  • The error continues to be the same this way. But the function is already called that way you say, I just call the component in another function with : ``, where `station` here is the json response. – jbssm Jan 03 '17 at 12:40