Reputation: 881
Hello I have problem in React-Typescript inside Redux toolkit. I get an error
'push' does not exist on type 'string | string[] | WritableDraft<Recipe>[] | WritableDraft<{ recipes: Recipe[]; totalAmount: number; }>'.
Property 'push' does not exist on type 'string'.
How to solve it because it looks that key has a lot of types and I can not get an object using state['key']. How to solve it? I am stuck.
export interface InitialState {
recipes: Recipe[];
likedRecipes: {
recipes: Recipe[];
totalAmount: number;
};
recipeTypes: string[];
recipeTime: string[];
recipeTitle: string;
filterTypes: string[];
filterLengths: string[];
}
export type FilteringConfiguration = {
content: string;
type: typeOfFiltering;
filterName: Omit<
keyof InitialState,
"recipes" | "likedRecipes" | "recipeTitle"
>;
};
redux slice
const INITIAL_VALUE: InitialState = {
recipes: [],
likedRecipes: {
recipes: [],
totalAmount: 0,
},
recipeTypes: ["Breakfast", "Lunch", "Dinner", "Supper"],
recipeTime: [
"Very short (~30min)",
"short (~1hr)",
"medium (~3hrs)",
"Long (~6hrs)",
],
// variables for filtering recipes
recipeTitle: "",
filterTypes: [],
filterLengths: [],
};
const recipeSlice = createSlice({
name: "recipe",
initialState: INITIAL_VALUE,
reducers: {
addFilters(state, action: PayloadAction<FilteringConfiguration>) {
const arr = state[action.payload.filterName];
if (Array.isArray(arr)) arr.push(action.payload.content);
},
UPDATE: I edited add filters but I got next error
Type 'Omit<keyof InitialState, "recipes" | "likedRecipes" | "recipeTitle">' cannot be used as an index type.
Upvotes: 2
Views: 7830
Reputation: 31655
You are getting this error because it's possible that the type you are using doesn't have a .push
method.
One way to handle this is check if it's an array before calling .push
.
const recipeSlice = createSlice({
name: "recipe",
initialState: INITIAL_VALUE,
reducers: {
addFilters(state, action: PayloadAction<FilteringConfiguration>) {
const arr = state[action.payload.filterName]
if (Array.isArray(arr)) arr.push(action.payload.content);
}, // THERE IS AN ERROR
})
This will solve the typescript error, but maybe you would need to do something when it's not an array and it's not possible to call .push
, probably in a else
statement.
The biggest problem you have is that you assume all keys from InitialState
have values that are an array of string (string[]
), which is not true, because you have a string
, and object and an array of Recipe
too.
In FilteringConfiguration
you define the content
as string
, assuming you will always push a string
, but because you have other values, this type is also incorrect.
I have no idea how to continue with this, because I don't know if you also want to allow to update the other keys of InitialValues
or not, but on solution would be to also ignore the keys from InitialValues
that aren't an array of strings.
export type FilteringConfiguration = {
content: string;
type: typeOfFiltering;
filterName: Exclude<keyof InitialState, 'recipes' | 'likedRecipes' | 'recipeTitle'>; // exclude keys that aren't string[]
};
You can check the docs for Exclude
Upvotes: 5