如何获取 TypeScript 对象和对象数组的嵌套键

3
为了一个表单生成器,我正在尝试为嵌套对象和对象数组获得类型安全性。我希望名称属性的值是它所属对象的键。
因此,在下面的示例中,name.name 的值必须为 "name"。
对于数组,对象的名称必须是嵌套在 choices 中的类型。因此,具有名称为 "parentOption" 的对象和具有名称为 "code" 的选项。
对于嵌套对象,它必须一直嵌套到最后一个属性,并且我希望对象属性和名称被输入。我的意思是,
Position > Location > x | y | z 是唯一允许提供的名称。
我希望这有点意义。使用 T 的 Keyof,我只能为表单对象的第一层级进行输入,因此问题、选择和位置都已输入。但是对于更深层次,我必须使用递归,但迄今为止我没有成功,谢谢!

type FormSchema = {
  name: string
  choices: { choice: string }[]
  position: { location: { x: number, y: number, z: number } }
}

type TextField = {
  name: string
  label: string
}

const form = {
  name: {
    name: "name", // name must be name
    label: "Question A"
  },
  choices: [
    {
      name: "choice", //name must be choice
      label: "Choice"
    }
  ],
  position: { //this has to be position
    location: { //this has to be location
      x: {name: "x", label: "X"}, //name must be x
      y: {name: "y", label: "Y"}, //name must be y
      z: {name: "z", label: "Z"}, //name must be z
    },
  }
}

输入图像描述 我添加了一张图片,以便更清楚地说明我的需求。所有与类型相连接的属性都应该自动定义类型。但是,它必须是动态的,以便任何使用的类型都可以自动定义类型。


看起来更像是一个映射器而不是一个类型。 - Konrad
1个回答

0

我不确定你想做什么,但表单似乎是这种类型

type FormSchema = {
  question: { id: 'question'; label: string };
  choices: { id: 'choice'; label: string }[];
  position: { location: { x: number, y: number, z: number } } ;
}

希望它有所帮助


位置不同。 - Konrad
我在顶部添加了一张图片,希望它能让问题更加清晰。FormSchema只是一个例子,键可以是任何动态字符串。因此,我想要一个接受泛型类型T的FormSchema类型,并且T的所有键都应以树形结构方式进行类型化。谢谢! - Re-Angelo
好的。我可以问一下为什么你想要(例如使用 questionquestion: { id: 'question', label: 'Question } 吗?由于 question.id 简单地等于 question,我不认为 id 属性有任何附加值,似乎你可以简单地使用 question: 'Question'。@Re-Angelo - Jérémy Rippert
@JérémyRippert 嗯,原因是最终id/name属性会被传递到React组件中。所以<Input id={id} name={name} label={label}/>。 - Re-Angelo
@Re-Angelo 即使使用这种方法,您也可以将键用作变量,因此如果您有 const form = { question1: 'Question 1', question2: 'Question 2' },您可以像这样迭代 Object.keys(form)(结果是 ['question1', 'question2']):Object.keys(form).map(key => <input id={key} name={key} label={form[key]} /> - Jérémy Rippert

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