Home > database >  type 'undefined' is not assignable to type, losing type in map()
type 'undefined' is not assignable to type, losing type in map()

Time:09-21

I have an action in my redux toolkit that's attempting to set some state. Relevant code below:

interfaces

export interface ProposalTag {
  id: number;
  name: string;
  hex: string;
  color: string;
}

export interface ProposalSelectedTag {
  proposal_id: number;
  proposal_tag_id: number;
}

redux

import { ProposalTag, ProposalSelectedTag } from '../../types/proposalTags';

interface ProposalTagsSlice {
  proposalTags: ProposalTag[];
  selectedProposalTags: ProposalTag[];
}

const initialState: ProposalTagsSlice = {
  proposalTags: [],
  selectedProposalTags: [],
};

const matchTags = (
  selectedTags: ProposalSelectedTag[],
  proposalTags: ProposalTag[],
): ProposalTag[] => {
  const tags = selectedTags.map((selectedTag: ProposalSelectedTag) => {
    return proposalTags.find(proposalTag => proposalTag.id === selectedTag.proposal_tag_id);
  });

  return tags ?? [];
};

export const proposalTagsSlice = createSlice({
  name: 'proposalTags',
  initialState,
  reducers: {
    setSelectedProposalTags: (state, action: PayloadAction<ProposalSelectedTag[]>) => {
      if (state.proposalTags === undefined) return;
      state.selectedProposalTags =
        action.payload === null ? [] : matchTags(action.payload, state.proposalTags);
    },
  },
});

The goal of matchTags is to convert the payload of ProposalSelectedTag[] to ProposalTag[]. So in theory, ProposalSelectedTag.proposal_tag_id

The type errors I get back are the following:enter image description here

Did I lose typing somewhere in matchTags?

CodePudding user response:

That's because Array.prototype.find will return undefined if the element is not found.

If you are sure that the item exists in the list, you can make an assertion that will calm TypeScript down.

const tags = selectedTags.map((selectedTag: ProposalSelectedTag) => {
  const item = proposalTags.find(proposalTag => proposalTag.id === selectedTag.proposal_tag_id);
  if (!item) throw new Error('item was not found')
  return item
});

You can also use !

const tags = selectedTags.map((selectedTag: ProposalSelectedTag) => {
  return proposalTags.find(proposalTag => proposalTag.id === selectedTag.proposal_tag_id)!;
});

Or you can set a default value

const tags = selectedTags.map((selectedTag: ProposalSelectedTag) => {
  return proposalTags.find(proposalTag => proposalTag.id === selectedTag.proposal_tag_id) ?? 10;
});
  • Related