如何用TypeScript验证AWS CDK Context JSON配置?
解决AWS CDK上下文JSON的TypeScript运行时类型校验问题
TypeScript的类型断言(as Environments)仅在编译阶段起作用,运行时不会验证JSON内容是否符合类型定义——这就是为什么你修改isEnabled为非布尔值也不会报错的原因。要确保JSON配置和TypeScript类型一致,必须添加运行时校验逻辑,以下是具体实现方案:
方案:使用Zod进行运行时校验
Zod是一款轻量的TypeScript运行时校验库,能同时生成编译时类型和运行时校验规则,避免重复定义。
步骤1:安装Zod
在CDK项目中安装依赖:
npm install zod # 或使用yarn yarn add zod
步骤2:定义Zod Schema并生成TypeScript类型
替换你原来的手动类型定义,用Zod schema自动推导类型:
import { z } from "zod"; // 定义单个环境配置的schema,将可选字段标记为.optional() const EnvironmentConfigurationSchema = z.object({ account: z.string(), region: z.string(), externalEndpoint: z.string().url(), // 额外校验URL格式 optionalExternalEndpoint: z.string().url().optional(), // 标记为可选字段 isEnabled: z.boolean(), }); // 定义多环境配置的schema const EnvironmentsSchema = z.record(z.string(), EnvironmentConfigurationSchema); // 自动推导TypeScript类型,无需手动定义 type EnvironmentConfiguration = z.infer<typeof EnvironmentConfigurationSchema>; type Environments = z.infer<typeof EnvironmentsSchema>;
步骤3:添加校验逻辑
在获取CDK上下文后,使用Zod的parse或safeParse方法校验配置:
// 获取上下文配置 const rawEnvironments = scope.node.tryGetContext('environments'); // 严格校验:如果不符合schema,直接抛出错误 const environments = EnvironmentsSchema.parse(rawEnvironments) as Environments; // 或者使用safeParse做容错处理(可选) // const result = EnvironmentsSchema.safeParse(rawEnvironments); // if (!result.success) { // throw new Error(`环境配置校验失败:${result.error.message}`); // } // const environments = result.data;
关键说明
z.string().url():除了校验类型,还能确保字段是合法的URL格式,提升配置可靠性。optional():对应你JSON中的可选字段,避免必填校验导致的错误。parse方法会在校验失败时抛出明确的错误信息,帮助快速定位配置问题;safeParse则返回结果对象,方便自定义错误处理。
其他可选方案:手动编写校验函数
如果不想引入第三方库,也可以手动编写校验函数:
function validateEnvironments(raw: unknown): asserts raw is Environments { if (typeof raw !== 'object' || raw === null) { throw new Error('environments配置必须是对象'); } for (const [envName, config] of Object.entries(raw)) { if (typeof config !== 'object' || config === null) { throw new Error(`环境${envName}的配置必须是对象`); } // 校验必填字段 const requiredFields: (keyof EnvironmentConfiguration)[] = ['account', 'region', 'externalEndpoint', 'isEnabled']; for (const field of requiredFields) { if (!(field in config)) { throw new Error(`环境${envName}缺少必填字段:${field}`); } } // 校验字段类型 if (typeof (config as any).account !== 'string') { throw new Error(`环境${envName}的account必须是字符串`); } if (typeof (config as any).isEnabled !== 'boolean') { throw new Error(`环境${envName}的isEnabled必须是布尔值`); } // 可选字段类型校验 if ('optionalExternalEndpoint' in config && typeof (config as any).optionalExternalEndpoint !== 'string') { throw new Error(`环境${envName}的optionalExternalEndpoint必须是字符串`); } } } // 使用校验函数 const rawEnvironments = scope.node.tryGetContext('environments'); validateEnvironments(rawEnvironments); const environments = rawEnvironments as Environments;
不过手动编写校验函数容易遗漏规则,且维护成本高,推荐使用Zod这类成熟库。
内容的提问来源于stack exchange,提问作者Rapiernik
相关产品推荐
相关产品推荐

