Promise.all error - Type '(Video | undefined)[]' is not assignable to type 'Video[]'

Viewed 174

I've got a problem with type for Promises.all. It supposed to return my Video[] interface but I got an error like

Type '(Video | undefined)[]' is not assignable to type 'Video[]'. Type 'Video | undefined' is not assignable to type 'Video'. Type 'undefined' is not assignable to type 'Video'.

when I change it into (Video | undefined)[] my whole typing I've got error it should have been Video[] again.

My code is here:

  const getDemo = async () => {
    setError({ show: false, msg: "" });
    try {
      setIsLoading(true);
      const resp: Video[] = await Promise.all(
        ourData.map(async (item) => {
          if (item.type === videoConstants.TYPE_YOUTUBE) {
            return getYouTubeVideo(item.id);
          }
          if (item.type === videoConstants.TYPE_VIMEO) {
            return getVimeoVideo(item.id);
          }
        })
      );
      setData([...data, ...resp]);
    } catch {
      setError({ show: true, msg: "failed to watch demo" });
    }
    setIsLoading(false);
  };

I'm using my own function to fetch API to keep rules of "DRY" - when I fetch a single object is okay, but when I use for Promise.all to get all collection from our DataBase I've got an error I cannot handle with.

1 Answers

The code below:

if (item.type === videoConstants.TYPE_YOUTUBE) {
  return getYouTubeVideo(item.id);
}
if (item.type === videoConstants.TYPE_VIMEO) {
  return getVimeoVideo(item.id);
}

will have return type as Video | undefined because there is no else block.

You can try this (if item.type can only take the two values present in videoConstants):

if (item.type === videoConstants.TYPE_YOUTUBE) {
  return getYouTubeVideo(item.id);
}
return getVimeoVideo(item.id);

or maybe:

if (item.type === videoConstants.TYPE_YOUTUBE) {
  return getYouTubeVideo(item.id);
}
if (item.type === videoConstants.TYPE_VIMEO) {
  return getVimeoVideo(item.id);
}
return {} as Video // TODO: depends on Video

or if you can do none of the above, this maybe your last option - const resp: (Video|undefined)[] = ...

Related