Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript TS:从动态对象的键创建映射类型_Javascript_Typescript_Typescript Typings_Reduce - Fatal编程技术网

Javascript TS:从动态对象的键创建映射类型

Javascript TS:从动态对象的键创建映射类型,javascript,typescript,typescript-typings,reduce,Javascript,Typescript,Typescript Typings,Reduce,我意识到在TS中键入.reduce非常困难,我所尝试的可能不可能。但无论如何,我想听听关于如何最好地键入以下内容的建议: 假设我有一组人: const people = [ { id: '1' }, { id: '2' }, { id: '3' }, ] 我正在用Formik制作一个表单,以便您可以输入这些人的姓名。我希望该表单的值的结构类似于值。1.名称,其中1是该人的id const initialValues = people.reduce((acc,

我意识到在TS中键入
.reduce
非常困难,我所尝试的可能不可能。但无论如何,我想听听关于如何最好地键入以下内容的建议:

假设我有一组

  const people = [
    { id: '1' },
    { id: '2' },
    { id: '3' },
  ]
我正在用
Formik
制作一个表单,以便您可以输入这些人的姓名。我希望该表单的
的结构类似于
值。1.名称
,其中
1
是该人的
id

  const initialValues = people.reduce((acc, p) => ({
    ...acc,
    [p.id]: {
      name: '',
    },
  }), {});
在使用表单时,理想情况下,我希望将
值键入如下内容:

  interface Values {
    [key: '1' | '2' | '3']: string;
  }
问题是默认情况下,
.reduce
将键入我的
初始值
并最终键入为
{}
,因此尝试访问
值[person.id]
将导致错误

我看到你可以做到这一点:

const peopleIds = {
    one: true,
    two: true,
    three: true,
  };

  type PeopleIds = keyof typeof peopleIds;
如果我的
人员列表始终是静态的,这将非常有用。本质上,我希望将
作为一个对象键入,其中可能的键是所有
people.id

可以理解,这有点复杂,但我想知道这在TS中是否可行,因为我将依靠
.reduce
之类的东西来生成表单的模式等等


谢谢

只要跟踪
people
数组元素的
id
属性中的文字值,就可以表示类型。最简单的方法是使用:

那么你要找的类型是

type InitValueType = Record<typeof people[number]['id'], { name: string }>;
/* type InitValueType = {
    1: {
        name: string;
    };
    2: {
        name: string;
    };
    3: {
        name: string;
    };
} */
该类型断言不是完全类型安全的;它并不能阻止一些不好的事情发生:

const badInitialValues = people.reduce((acc, p) => ({
    ...acc,
    [p.id]: {
        kablam: '', // what?
    },
}), {} as InitValueType);
但这可能是您在这里可以合理地做到的最好的方法,因为尝试为
reduce()
提供一个类型,它表示单个回调,表示以
{}
开始并最终以
InitValueType
结束的类型链中的每个链接,这将非常混乱,并且不可能最终为您带来更多安全性

好吧,希望这会有帮助;祝你好运

const initialValues = people.reduce((acc, p) => ({
    ...acc,
    [p.id]: {
        name: '',
    },
}), {} as InitValueType);
const badInitialValues = people.reduce((acc, p) => ({
    ...acc,
    [p.id]: {
        kablam: '', // what?
    },
}), {} as InitValueType);