使用 TypeScript 过滤对象键

4
这里是一个展示问题的沙箱。https://codesandbox.io/s/trusting-moon-n058k?file=/src/index.ts 输入:
data.types = {
        starter: true,
        main: false,
        side: false,
        dessert: true,
        drink: false
    }

期望的输出

recipe.types = ["starter", "dessert"]

解决方案

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]
  );
};

问题: 无论我使用什么类型,Typescript都不会停止报错。
任何帮助都将不胜感激,因为我快要疯了。

1
JSON.parse(JSON.stringify(data)) 的意义是什么?它会生成 data 的部分深度克隆,但你并不需要这样做。 - axiac
@axiac 不是我这么做的吗?https://codesandbox.io/s/quizzical-cori-zrsio?file=/src/index.js 我不想改变“data”。 - Azaghlou
没事,我不需要了。TIL - Azaghlou
你不会改变 data。至少在问题中发布的代码中不会。但是在 let recipe = { ...data }; recipe.types.starter = true; 中,你确实会改变 data - axiac
是的,我在测试后注意到了这一点,但无法编辑我的评论。谢谢你指出来!这解决了我一个误解。 - Azaghlou
1个回答

5
错误发生是因为编译器不能推断出key的运行时类型,因为Object.keys可以返回任意一组不一定是NewRecipeFormValues["types"]类型的字符串。
因此,您需要明确告诉编译器key确实是NewRecipeFormValues["types"]keyof类型,以便它能够安心工作。
为了做到这一点,请使用类型断言
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"]]
  );
};

查看这个游乐场

至于为什么你不能使用key:keyof NewRecipeFormValues [“types”] 语法,链接的文档解释得更好。


非常感谢!我不知道我们可以在 [] 内使用类型断言。 - Azaghlou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接