用途
migrate-to-shoehorn 用于把测试文件中的 as 类型断言迁移到 @total-typescript/shoehorn。它解决的核心问题是:在测试中经常需要传入部分数据,但又希望 TypeScript 保持类型检查通过。shoehorn 允许传入部分数据同时让 TypeScript 满意,用类型安全的方案替代 as 断言。
主要能力
该技能针对测试代码中 as 断言带来的问题提供迁移方案。资料指出的问题包括:开发者被训练为尽量避免使用 as;必须手动指定目标类型;对故意错误的数据需要使用双重断言 as unknown as Type。
技能提供三类辅助函数及其适用场景:
fromPartial():传入仍然能通过类型检查的部分数据。fromAny():传入故意错误的数据(同时保留自动补全)。fromExact():强制完整对象(后续可与 fromPartial 互换)。
使用方式
安装命令:
npm i @total-typescript/shoehorn
迁移模式一:处理大对象但只需要少量属性。
迁移前:
type Request = {
body: { id: string };
headers: Record<string, string>;
cookies: Record<string, string>;
// ...20 more properties
};
it("gets user by id", () => {
// Only care about body.id but must fake entire Request
getUser({
body: { id: "123" },
headers: {},
cookies: {},
// ...fake all 20 properties
});
});
迁移后:
import { fromPartial } from "@total-typescript/shoehorn";
it("gets user by id", () => {
getUser(
fromPartial({
body: { id: "123" },
}),
);
});
迁移模式二:as Type → fromPartial()。
迁移前:
getUser({ body: { id: "123" } } as Request);
迁移后:
import { fromPartial } from "@total-typescript/shoehorn";
getUser(fromPartial({ body: { id: "123" } }));
迁移模式三:as unknown as Type → fromAny()。
迁移前:
getUser({ body: { id: 123 } } as unknown as Request); // wrong type on purpose
迁移后:
import { fromAny } from "@total-typescript/shoehorn";
getUser(fromAny({ body: { id: 123 } }));
工作流程:
- 收集需求,向用户询问:哪些测试文件存在造成问题的
as断言;它们是否处理大对象而只关心部分属性;是否需要为错误测试传入故意错误的数据。 - 安装并迁移:
- 安装:
npm i @total-typescript/shoehorn - 查找包含
as断言的测试文件:
- 安装:
grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts"
- 将
as Type替换为fromPartial() - 将
as unknown as Type替换为fromAny() - 添加来自
@total-typescript/shoehorn的导入 - 运行类型检查以验证
适用场景
适用于测试文件中存在 as 类型断言并造成问题的情形,尤其是处理大对象但只关心部分属性、或需要传入故意错误数据以测试错误分支的场景。当用户提到 shoehorn、想要替换测试中的 as、或需要部分数据时使用。
限制
该技能仅用于测试代码。资料明确要求:绝不在生产代码中使用 shoehorn。