Problem: TypeScript Error Calling .map() on an Array Union Type
I was running into a TypeScript issue trying to call Array.prototype.map()
over an uploadedDocuments
array of items in a React component <UserDocumentList />
that renders a list of uploaded documents.
UserDocumentList.tsx
import React from "react";
import { FileWithPath } from "react-dropzone";
import { S3Document } from "~/api/user/getUserDocuments";
type Props = {
uploadedDocuments: S3Document[] | FileWithPath[];};
const UserDocumentList: React.FC<Props> = ({ uploadedDocuments, intl }) => {
return (
<div>
{uploadedDocuments.map((document, i: number) => { // ... render my list items
})}
</div>
);
};
export default UserDocumentList;
Depending on where my <UserDocumentList />
component is used, uploadedDocuments
can either render a list of S3Document[]
documents or FileWithPath[]
documents.
Naively, I declared the type of uploadedDocuments
as:
type Props = {
uploadedDocuments: S3Document[] | FileWithPath[];};
However, TypeScript did not like this:
This expression is not callable.
Each member of the union type '(<U>(callbackfn: (value: FileWithPath, index: number, array: FileWithPath[]) => U, thisArg?: any) => U[]) | (<U>(callbackfn: (value: S3Document, index: number, array: S3Document[]) => U, thisArg?: any) => U[])' has signatures, but none of those signatures are compatible with each other.ts(2349)
Solution:
Apparently, for union types, members which are functions will also be typed as union types, so the the type of Array.prototype.map
is not callable.
To fix this issue, the correct typing of uploadedDocuments
should be an array of the union of S3Document
and FileWithPath
types.
type Props = {
uploadedDocuments: (S3Document | FileWithPath)[];};