2
votes

There's a script in my program that eventually calls a function that accepts a string and runs .match(regex) on that string.


As per MDN:
String.prototype.match(regex) returns an array data type of which I only need to access the first index [0]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match



In every way I've tried to re-organize this script I get the flow error:

"Cannot get findStationId(...)[0] because an index signature declaring the expected key / value type is missing in null [1]."

The Organization of the function isn't where I'm having trouble, but with the [0] index reference.



How can I correctly type check this and declare the expected values?

// @flow

type RssResults = Array<{
  title: string,
  contentSnippet: string
}>

const findStationId = (string: string): Array<any> | null => string.match(/([0-9]{5}|[A-Z\d]{5})/)

export default (rssResults: RssResults) => {
  const entries = []
  rssResults.forEach((entry) => {
    const observation = {}
    observation.title = entry.title
    const id = findStationId(entry.title)[0] // flow errors here on [0]
    observation.id = id.toLowerCase()

    // ...        

    entries.push(observation)
  })
return entries
}


.flowconfig

[ignore]
.*/test/*

[include]

[libs]

[lints]

[options]
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json
module.file_ext=.css
module.file_ext=.scss
module.name_mapper.extension='css' -> 'empty/object'
module.name_mapper.extension='scss' -> 'empty/object'

[strict]

[untyped]
.*/node_modules/**/.*

Thank you!

1

1 Answers

3
votes

If you look closer at that MDN page, it states:

An Array whose contents depend on the presence or absence of the global (g) flag, or null if no matches are found.

with "null if no matches are found." being the critical part here. null[0] does not make sense. Your own return type Array<any> | null also mentions this.

So either your

const id = findStationId(entry.title)[0]

should do

const match = findStationId(entry.title)
if (!match) throw new Error("No station ID found")
const id = match[0]

or you should change findStationId to not allow a null return.

const findStationId = (string: string): Array<any> => {
  const match = string.match(/([0-9]{5}|[A-Z\d]{5})/)
  if (!match) throw new Error("No station ID found")
  return match
}