Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argument of type 'any' is not assignable to type 'never'

I am fetching images from an endpoint and having trouble pushing each mapped file into my local array. I am receiving the error Argument of type 'any' is not assignable to type 'never'.

  • I tried setting all arguments to blob to no success.
  • Tried setting function(data) to data: any, data: {}, data: File[], data: JSON and all say map functionality does not work on these types.
  • I think the problem may be within my state.mediaLibrary. Perhaps that is where I need to assign the array type?
import * as React from "react"
import { Company } from "data/companies"
import { Asset } from "data/companies"

interface MediaLibraryProps {
  company: Company
}

class MediaLibrary extends React.Component<MediaLibraryProps> {
  state = {
    mediaLibrary: []
  }

  getMediaLibrary = async () => {
    await fetch(
      `${process.env.REACT_APP_SA_API_URL}/${this.props.company.id}/medialibrary`,
    ).then(blob => blob.json())
      .then(function (data) {
        return data.map((file: Asset) => {
          return {
            id: file.assetId,
            path: file.path
          }
        })
      }).then(data => this.state.mediaLibrary.push(...data))
  }

  public render() {
    const files = this.state.mediaLibrary.map((file: Asset) => (
      <div key={file.assetId}>
        <div>
          <img src={`url(${process.env.REACT_APP_SA_CDN_URL}${file.path})`} />
        </div>
      </div>
    ))

    return (
      <div>
        <div>
          <h2>Media Library</h2>
          {files}
          <button onClick={this.getMediaLibrary}>Get Files</button>
        </div>
      </div>
    )
  }
}

export default MediaLibrary
  • Expect the state array to be populated with many image files.
  • Actual results are TypeScript is complaining.

IMPORTANT: After solving this issue I found my problem was not with the state. Although the solution allows me to push objects into the array I was mutating the state directly which is a nono in React. See below:

class MediaLibrary extends React.Component<MediaLibraryProps> {
  state = {
    mediaLibrary: []
  }

  getMediaLibrary = async () => {
    await fetch(
      `${process.env.REACT_APP_SA_API_URL}/${this.props.company.id}/medialibrary`
      }
    ).then(blob => blob.json())
      .then(function (data: any) {
        return data.map((file: Asset) => Object.assign(file, {
          assetId: file.assetId,
          path: file.path
        }))
      }).then((data) => this.setState({ mediaLibrary: [...data] }))
  }
like image 828
Prozak Avatar asked May 02 '19 12:05

Prozak


1 Answers

You should declarate your mediaLibrary array like this:

state = {
  mediaLibrary: Array<{id: string, path: string}>()
}

or like this:

state: {
  mediaLibrary: {id: string, path: string}[]
} = {
  mediaLibrary: []
}

With the first way you're telling TypeScript you want to put objects with the given attributes inside the mediaLibrary array. With just [] TypeScript will put the never type to the array and hence fails to put anything into it.

The second example describes the complete state object and not just the included array.

like image 141
Björn Böing Avatar answered Sep 24 '22 13:09

Björn Böing