如何测试或强制校验TypeScript对象上的字符串为合法嵌套属性?
解决方案
1. 给fieldOrder数组增加合法嵌套键类型约束
你可以通过TypeScript递归泛型实现点分隔嵌套路径的类型校验,编码阶段就能拦截非法路径输入,实现代码如下:
// 通用递归工具类型:生成目标类型T的所有合法点分隔嵌套路径 type NestedPath<T> = T extends object ? { [K in keyof T & (string | number)]: K extends string ? `${K}` | `${K}.${NestedPath<T[K]>}` : never }[keyof T & (string | number)] : never; // 你的业务接口 interface PurchaseDetails { purchase: { date: string; details: string; }, returned: string; } // 声明该场景下的合法路径类型 type PurchaseDetailsFieldPath = NestedPath<PurchaseDetails> // 合法赋值:不会报错 const fieldOrder1: PurchaseDetailsFieldPath[] = [ "purchase.date", "returned", "purchase.details", ] // 非法赋值:TS会直接标红提示路径不存在 const fieldOrderError: PurchaseDetailsFieldPath[] = [ "purchase.invalidKey", "returned" ]
如果你的业务类型中包含数组结构,只需要调整NestedPath的递归逻辑,即可支持下标格式的路径(如purchase.items.2.price)。
2. 无需模拟对象的TypeScript类型合法性单元测试
TypeScript的类型校验是编译时逻辑,不需要运行时模拟对象即可完成合法性校验,有两种常用方案:
方案1:用tsd做专门的类型单元测试
tsd是专门用于TypeScript类型校验的测试工具,不需要写任何运行时代码和模拟对象,步骤如下:
- 安装依赖:
npm install tsd -D - 新建类型测试文件
field-order.test-d.ts:
import { expectType, expectError } from 'tsd' import type { PurchaseDetails, NestedPath, PurchaseDetailsFieldPath } from './你的类型定义文件路径' // 测试合法路径数组可通过类型校验 expectType<PurchaseDetailsFieldPath[]>([ "purchase.date", "returned", "purchase.details", ]) // 测试含非法路径的数组会抛出类型错误 expectError<PurchaseDetailsFieldPath[]>([ "purchase.invalidKey", "returned" ])
- 在package.json中增加测试脚本:
{ "scripts": { "test:types": "tsd" } }
运行npm run test:types即可完成所有类型合法性校验,整个过程不会执行任何业务代码,也不需要构造模拟对象。
方案2:直接靠项目编译校验
如果不想引入额外工具,可以把所有需要校验的fieldOrder数组都显式声明为NestedPath<目标类型>[]类型,只要项目正常编译通过,就说明所有路径都是合法的,编译报错即说明存在非法路径,也不需要额外编写测试用例和模拟对象。
内容的提问来源于stack exchange,提问作者MattTreichel
相关产品推荐
相关产品推荐

