如何校验字符串数组是否匹配TypeScript接口的所有属性名?
校验字符串数组与TypeScript接口属性名完全匹配的方案
由于无法使用ts-transformer-keys这类需要修改webpack配置的工具,以下是几种纯TypeScript语法层面的编译时校验方案,无需额外构建工具配置:
方案一:对象字面量中转法
利用TypeScript对对象键的严格类型检查,先定义一个与接口属性完全匹配的对象,再提取其键作为目标数组。这种方式最直观,少写/多写属性都会直接触发编译错误:
export interface MyType1 { propName1: number; propName2: string; propNameX: number; } // 定义与接口属性完全匹配的占位对象,属性缺失或冗余都会报错 const keysPlaceholder: { [K in keyof MyType1]: unknown } = { propName1: null, propName2: null, propNameX: null }; // 提取对象键作为目标数组,类型自动推导为接口属性名的联合类型数组 const tableColumns = Object.keys(keysPlaceholder) as (keyof MyType1)[];
方案二:元组+类型断言+辅助类型校验
通过const断言将数组转为只读元组,再用辅助类型强制校验元组元素是否覆盖接口所有属性,且无额外属性:
export interface MyType1 { propName1: number; propName2: string; propNameX: number; } // 用const断言锁定数组元素为字面量类型,避免类型拓宽 const tableColumns = ['propName1', 'propName2', 'propNameX'] as const; // 辅助类型:检查元组元素是否完全匹配接口属性集 type AssertExactMatch<T, U extends readonly (keyof T)[]> = keyof T extends U[number] ? (U[number] extends keyof T ? true : never) : never; // 编译时校验:如果数组与接口属性不匹配,这里会抛出类型错误 type _ = AssertExactMatch<MyType1, typeof tableColumns>;
方案三:satisfies运算符+辅助类型(TS 4.9+)
利用TypeScript 4.9新增的satisfies运算符,既保留数组的字面量类型,又约束其元素为接口属性名,再配合辅助类型校验属性完整性:
export interface MyType1 { propName1: number; propName2: string; propNameX: number; } // 用satisfies约束数组元素只能是接口属性名,同时保留字面量类型 const tableColumns = [ 'propName1', 'propName2', 'propNameX' ] satisfies (keyof MyType1)[]; // 辅助类型:校验数组是否包含所有接口属性 type HasAllInterfaceKeys<T, U extends (keyof T)[]> = keyof T extends U[number] ? true : false; // 强制校验,不匹配则编译报错 type _ = HasAllInterfaceKeys<MyType1, typeof tableColumns> extends true ? true : never;
所有方案均在编译阶段完成校验,无需运行时代码,也不需要修改任何构建工具配置。
内容的提问来源于stack exchange,提问作者Sergino
相关产品推荐
相关产品推荐

