数组元素子类型

时间:2019-10-09 09:50:55

标签: javascript typescript types formik yup

有关从数据结构构造类型的问题。 我有一个像这样的数组:

interface ICVSection {
  namespace: string;
  validation: Yup.ObjectSchema<any>;
}

const CVSections: ICVSection[] = [
  {
    namespace: 'common',
    validation: CommonValidationSchema,
  },
  {
    namespace: 'summary',
    validation: SummarySchema,
  }
  /* ... */
};

所以问题是:是否可以以某种方式使用上面的数据创建以下类型:

type Schema = {
  common: typeof CommonValidationSchema,
  namespace: typeof SummarySchema,
  /* ... */
}

我不确定100%是否可以在TypeScript中使用,但如果可以,那么如果有人可以证明我是对还是错,那就太好了。

1 个答案:

答案 0 :(得分:2)

这是我想出的解决方案:

[Errno 2] No such file or directory: 'php'
[cmd: ['php', '/home/osboxes/.config/sublime-text-3/Packages/User/test.php']]
[dir: /home/osboxes/.config/sublime-text-3/Packages/User]
[path: /home/osboxes/bin:/home/osboxes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin]
[Finished]

但是要使其工作,我们需要稍微更改数组定义。不必将其键入type namespaces = typeof CVSections[number]['namespace']; type Schema = { [K in namespaces]: Pick<Extract<typeof CVSections[number], { namespace: K }>, 'validation'>['validation']>; }; ,而必须将其定义为ICVSection[],以使TypeScript缩小可能的const CVSections = [ /* ... */ ] as const;值。

在我的情况下,由于我将Yup库与Formik一起用于验证架构,因此我可以应用其他类型转换以将Yup的架构类型解包为普通TypeScript类型。最终解决方案如下所示:

namespaces

然后,我们可以将此类型应用于type Schema = { [K in namespaces]: Yup.InferType<Pick<Extract<typeof CVSections[number], { namespace: K }>, 'validation'>['validation']>; }; 组件以强制进行类型验证:

<Formik>