数组元素子类型
Array element child type
关于数据结构类型构造的问题。
我有一个这样的数组:
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 中是否可行,但如果是这样,如果有人能证明我是对还是错,那就太好了。
所以这是我想出的解决方案:
type namespaces = typeof CVSections[number]['namespace'];
type Schema = {
[K in namespaces]: Pick<Extract<typeof CVSections[number], { namespace: K }>, 'validation'>['validation']>;
};
但是为了让它工作,我们需要稍微改变我们的数组定义。我们必须将其定义为 const CVSections = [ /* ... */ ] as const;
,而不是将其键入 ICVSection[]
,以允许 TypeScript 缩小可能的 namespaces
值。
就我而言,由于我将 Yup 库与 Formik 一起用于验证模式,我可以应用额外的类型转换将 Yup 的模式类型解包为纯 TypeScript 类型。最终解决方案将如下所示:
type Schema = {
[K in namespaces]: Yup.InferType<Pick<Extract<typeof CVSections[number], { namespace: K }>, 'validation'>['validation']>;
};
然后我们可以将此类型应用于 <Formik>
组件以强制执行类型验证:
<Formik<Schema>
initialValues={{
common: {
/* mandatory values */
},
summary: {
/* mandatory values */
}
}}
>
关于数据结构类型构造的问题。 我有一个这样的数组:
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 中是否可行,但如果是这样,如果有人能证明我是对还是错,那就太好了。
所以这是我想出的解决方案:
type namespaces = typeof CVSections[number]['namespace'];
type Schema = {
[K in namespaces]: Pick<Extract<typeof CVSections[number], { namespace: K }>, 'validation'>['validation']>;
};
但是为了让它工作,我们需要稍微改变我们的数组定义。我们必须将其定义为 const CVSections = [ /* ... */ ] as const;
,而不是将其键入 ICVSection[]
,以允许 TypeScript 缩小可能的 namespaces
值。
就我而言,由于我将 Yup 库与 Formik 一起用于验证模式,我可以应用额外的类型转换将 Yup 的模式类型解包为纯 TypeScript 类型。最终解决方案将如下所示:
type Schema = {
[K in namespaces]: Yup.InferType<Pick<Extract<typeof CVSections[number], { namespace: K }>, 'validation'>['validation']>;
};
然后我们可以将此类型应用于 <Formik>
组件以强制执行类型验证:
<Formik<Schema>
initialValues={{
common: {
/* mandatory values */
},
summary: {
/* mandatory values */
}
}}
>