【问题标题】:How to type nested objects with a value that matches its key in TypeScript?如何使用与其在 TypeScript 中的键匹配的值键入嵌套对象?
【发布时间】:2020-06-26 10:56:45
【问题描述】:

我有一个对象,例如:

const CATEGORIES = {
  diet: {
    id: 'diet',
    title: 'Diet',
    ...
  },
  ...
}

如何为它编写一个类型,以便 TypeScript 确保嵌套的 id 属性与父对象中的对象键匹配?

我试过了……

const CATEGORIES: {
  [T in string]: {
    id: T
    title: string
  }
} = { ... }

...但这似乎仍然接受id 的任何字符串。

我假设它以某种方式使用映射类型和泛型,但我无法完全弄清楚语法是什么,如果可能的话。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您无法映射所有string 并让它按照您想要的方式运行;见microsoft/TypeScript#22509。您需要一组 string literal 键来映射。实现此目的的一种方法是使用通用辅助函数,该函数从传入的值中推断出这些键,并验证每个属性的 id 子属性是否与其键匹配:

    const asCategories = <T extends { [K in keyof T]: { id: K, title: string } }>(t: T) => t;
    

    您可以测试看看它是否对良好的价值观感到满意:

    const CATEGORIES = asCategories({
      diet: {
        id: 'diet',
        title: 'Diet',
        //...
      },
      //...
    }); // okay
    

    对坏人生气:

    const BADCATEGORIES = asCategories({
      diet: { id: "diet", title: "Diet" },
      exercise: { id: "exersice", title: "Exercise" } // error!
      // -------> ~~
      // Type '"exersice"' is not assignable to type '"exercise"'.
    })
    

    好的,希望对您有所帮助;祝你好运!

    Playground link to code

    【讨论】:

    • 谢谢@jcalz!当我认为我已经尝试了所有方法时,我总是忘记使用恒等函数方法,但这是解决这些更复杂的打字问题的有趣方法。
    猜你喜欢
    • 2020-10-12
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    相关资源
    最近更新 更多