Here is a sandbox showing the issue. =/src/index.ts
Input :
data.types = {
starter: true,
main: false,
side: false,
dessert: true,
drink: false
}
Desired output :
recipe.types = ["starter", "dessert"]
Solution :
type NewRecipeFormValues = {
types: {
starter: boolean,
main: boolean,
side: boolean,
dessert: boolean,
drink: boolean
}
}
const postNewRecipe = (data: NewRecipeFormValues) => {
let recipe = JSON.parse(JSON.stringify(data));
recipe.types = Object.keys(data.types).filter(
(key: keyof NewRecipeFormValues["types"]) => data.types[key]
);
};
Problem : Typescript never shutups no matter what type I use.
Any help would be appreciated because I'm losing my mind
Here is a sandbox showing the issue. https://codesandbox.io/s/trusting-moon-n058k?file=/src/index.ts
Input :
data.types = {
starter: true,
main: false,
side: false,
dessert: true,
drink: false
}
Desired output :
recipe.types = ["starter", "dessert"]
Solution :
type NewRecipeFormValues = {
types: {
starter: boolean,
main: boolean,
side: boolean,
dessert: boolean,
drink: boolean
}
}
const postNewRecipe = (data: NewRecipeFormValues) => {
let recipe = JSON.parse(JSON.stringify(data));
recipe.types = Object.keys(data.types).filter(
(key: keyof NewRecipeFormValues["types"]) => data.types[key]
);
};
Problem : Typescript never shutups no matter what type I use.
Any help would be appreciated because I'm losing my mind
Share Improve this question asked Aug 22, 2021 at 15:19 AzaghlouAzaghlou 531 silver badge5 bronze badges 5-
1
What's the point of
JSON.parse(JSON.stringify(data))
? It produces a partial deep clone ofdata
but you don't need one. – axiac Commented Aug 22, 2021 at 15:32 -
@axiac no I do ? codesandbox.io/s/quizzical-cori-zrsio?file=/src/index.js I don't want to mutate
data
. – Azaghlou Commented Aug 22, 2021 at 15:54 - Nevermind indeed I don't. TIL – Azaghlou Commented Aug 22, 2021 at 16:02
-
You don't mutate
data
. At least not in the code posted in the question. You do mutatedata
inlet recipe = { ...data }; recipe.types.starter = true;
– axiac Commented Aug 22, 2021 at 16:12 - Yeah I noticed that after testing but couldn't edit my ment. Thanks for pointing that out! It fixed a misunderstanding I had. – Azaghlou Commented Aug 22, 2021 at 18:39
1 Answer
Reset to default 5The error happens because the piler cannot infer the runtime type of the key
because Object.keys
can return an arbitrary list of strings that are not necessarily keyof NewRecipeFormValues["types"]
type.
Therefore, you need to explicitly tell the piler that key
is indeed keyof NewRecipeFormValues["types"]
so that it can calm down.
To do that, use type assertion.
type NewRecipeFormValues = {
types: {
starter: boolean;
main: boolean;
side: boolean;
dessert: boolean;
drink: boolean;
};
};
const postNewRecipe = (data: NewRecipeFormValues) => {
let recipe = JSON.parse(JSON.stringify(data));
recipe.types = Object.keys(data.types).filter(
(key) => data.types[key as keyof NewRecipeFormValues["types"]]
);
};
Check this playground.
As for why you cannot use key: keyof NewRecipeFormValues["types"]
syntax, the linked documentation explains it better.