1

Result type prop is defined as follows. CalendarProp, ContactProp,... are predefined and all have different types.

type ResultProp =
    | { type: "calendar", data: CalendarProp }
    | { type: "contact", data: ContactProp }
    | { type: "dropbox", data: DropboxProp }
    | { type: "slack", data: SlackProp }
    | { type: "tweet", data: TweetProp }

Calendar Prop

interface CalendarProp {
    id: string,
    title: string,
    invitees: string,
    date: string,
    matching_terms: Array<string>
}

ContactProp type

interface ContactProp {
    id: string,
    name: string,
    company: string,
    emails: Array<string>,
    phones: Array<string>,
    last_contact: string,
    matching_terms: Array<string>
}

All the props have a different type. Component maintaining a result array is defined below. I am getting Typescript error while adding object to result array using useState hook. Here calendarData.calendar, ... is an array of json object.

const SearchResults: React.FC<QueryProp> = (props) => {
    const query = props.query;
    const [result, setResult] = useState<Array<ResultProp>>([]);
    
    useEffect(() => {
        if (query.length > 0){
            const files = [
                {
                    type: "calendar",
                    data: calendarData.calendar
                },
                {
                    type: "contact",
                    data: contactData.contacts
                }, 
                {
                    type: "dropbox",
                    data: dropboxData.dropbox
                },
                {
                    type: "slack",
                    data: slackData.slack
                },
                {
                    type: "tweet",
                    data: tweetData.tweet
                }
            ];

            for(const file of files){
                for(const d of file.data){
                    if (d.matching_terms.includes(query)) {
                        switch(file.type) {
                            case "calendar":
                                setResult([...result, { type: "calendar", data: d }]); // Error here
                                break;
                        }
                    }
                }
            }
        }
        return () => {
            setResult([]);
        }
    }, [query])

    return (
        <div className="search-results">
            {/* {result.map((r, index) => {
                return <Cardview key={index} {...r} />
            })} */}
        </div>
    )
}

I get the following error message:

Argument of type '({ type: "contact"; data: ContactProp; } | { type: "dropbox"; data: DropboxProp; } | { type: "slack"; data: SlackProp; } | { type: "tweet"; data: TweetProp; } | { ...; })[]' is not assignable to parameter of type 'SetStateAction<ResultProp[]>'.
  Type '({ type: "contact"; data: ContactProp; } | { type: "dropbox"; data: DropboxProp; } | { type: "slack"; data: SlackProp; } | { type: "tweet"; data: TweetProp; } | { ...; })[]' is not assignable to type 'ResultProp[]'.
    Type '{ type: "calendar"; data: { id: string; title: string; invitees: string; matching_terms: string[]; date: string; } | { id: string; name: string; company: string; emails: string[]; phones: string[]; matching_terms: string[]; last_contact: string; } | { ...; } | { ...; } | { ...; } | { ...; }; }' is not assignable to type 'ResultProp'.
      Types of property 'data' are incompatible.
        Type '{ id: string; title: string; invitees: string; matching_terms: string[]; date: string; } | { id: string; name: string; company: string; emails: string[]; phones: string[]; matching_terms: string[]; last_contact: string; } | { ...; } | { ...; } | { ...; } | { ...; }' is not assignable to type 'CalendarProp'.
          Type '{ id: string; name: string; company: string; emails: string[]; phones: string[]; matching_terms: string[]; last_contact: string; }' is missing the following properties from type 'CalendarProp': title, invitees, date
2
  • 1
    Can you post what CalendarProp and the others look like plus what shape calendarData.calendar etc have? Commented Sep 4, 2020 at 17:20
  • the files in the files array don't have a narrowable discriminant, type is just a string. Also, Based on the types you've added, the inner loop doesn't make sense and errors. Commented Sep 4, 2020 at 17:25

1 Answer 1

1

Here you test that file coming from files match the calendar type. But you never said to TypeScript the type of files. It's not sure for him what d really is so it can be CalendarProp or ContactProp or... You have 2 solutions to fix that:

  1. Declare the type of files:
const files: ResultProp[] = [
  ...

In this case, if file.type is "calendar", then TypeScript can deduce that data is of type CalendarProp.


  1. Cast the value of d to CalendarProp:
setResult([...result, { type: "calendar", data: d as CalendarProp }]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.