migrate-to-shoehorn
- 作者仓库星标 0
- 作者更新于 2026年8月24日 22:19
- 作者仓库 skills
Migrate to Shoehorn
Why shoehorn?
shoehorn lets you pass partial data in tests while keeping TypeScript happy. It replaces as assertions with type-safe alternatives.
Test code only. Never use shoehorn in production code.
Problems with as in tests:
- Trained not to use it
- Must manually specify target type
- Double-as (
as unknown as Type) for intentionally wrong data
Install
npm i @total-typescript/shoehorn
Migration patterns
Large objects with few needed properties
Before:
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
});
});
After:
import { fromPartial } from "@total-typescript/shoehorn";
it("gets user by id", () => {
getUser(
fromPartial({
body: { id: "123" },
}),
);
});
as Type → fromPartial()
Before:
getUser({ body: { id: "123" } } as Request);
After:
import { fromPartial } from "@total-typescript/shoehorn";
getUser(fromPartial({ body: { id: "123" } }));
as unknown as Type → fromAny()
Before:
getUser({ body: { id: 123 } } as unknown as Request); // wrong type on purpose
After:
import { fromAny } from "@total-typescript/shoehorn";
getUser(fromAny({ body: { id: 123 } }));
When to use each
| Function | Use case |
|---|---|
fromPartial() |
Pass partial data that still type-checks |
fromAny() |
Pass intentionally wrong data (keeps autocomplete) |
fromExact() |
Force full object (swap with fromPartial later) |
Workflow
Gather requirements - ask user:
- What test files have
asassertions causing problems? - Are they dealing with large objects where only some properties matter?
- Do they need to pass intentionally wrong data for error testing?
- What test files have
Install and migrate:
- Install:
npm i @total-typescript/shoehorn - Find test files with
asassertions:grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts" - Replace
as TypewithfromPartial() - Replace
as unknown as TypewithfromAny() - Add imports from
@total-typescript/shoehorn - Run type check to verify
- Install:
- 流狐分类
- 工程开发
- 作者声明 Agent
- 未找到明确声明;不据此推断已兼容或已测试
- 静态检查
- 88 / 100 · 启发式扫描,不代表运行安全
- 作者 / 版本 / 许可
- @mattpocock · 未声明 license
- 流狐 Token 估算
- 低消耗
- 流狐接入估算
- 即装即用
- 是否需要外部 API Key
- 未发现要求
- 检测到的系统要求
- macOS · Linux · Windows
- 底层运行要求
- 未声明
- 检测到的文件与系统行为
-
- 只读
- 检测到的网络行为
- 仅限本地
- 安装命令数
- 无(仅作为资料)
档案由构建时根据 SKILL.md 与安装命令自动衍生,可能与作者实际意图存在差异。
需要注意: 未限定 allowed-tools,默认拥有全部工具权限。
作者没有在当前 SKILL.md 中定义固定输出样例。 Why shoehorn?
shoehorn lets you pass partial data in tests while keeping TypeScript happy. It replaces as assertions with type-safe alternatives. Test code only. Never use shoehorn in production code. Problems with as in tests:
Install
Install
Migration patterns
Migration patterns
Large objects with few needed properties
Before: After:
as Type → fromPartial()
Before: After:
as unknown as Type → fromAny()
Before: After:
# Migrate to Shoehorn
## Why shoehorn?
`shoehorn` lets you pass partial data in tests while keeping TypeScript happy. It replaces `as` assertions with type-safe alternatives.
**Test code only.** Never use shoehorn in production code.
Problems with `as` in tests:
- Trained not to use it
- Must manually specify target type
- Double-as (`as unknown as Type`) for intentionally wrong data
## Install
```bash
npm i @total-typescript/shoehorn
```
## Migration patterns
### Large objects with few needed properties
Before:
```ts
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
});
});
```
After:
```ts
import { fromPartial } from "@total-typescript/shoehorn";
it("gets user by id", () => {
getUser(
fromPartial({
body: { id: "123" },
}),
);
});
```
### `as Type` → `fromPartial()`
Before:
```ts
getUser({ body: { id: "123" } } as Request);
```
After:
```ts
import { fromPartial } from "@total-typescript/shoehorn";
getUser(fromPartial({ body: { id: "123" } }));
```
### `as unknown as Type` → `fromAny()`
Before:
```ts
getUser({ body: { id: 123 } } as unknown as Request); // wrong type on purpose
```
After:
```ts
import { fromAny } from "@total-typescript/shoehorn";
getUser(fromAny({ body: { id: 123 } }));
```
## When to use each
| Function | Use case |
| --------------- | -------------------------------------------------- |
| `fromPartial()` | Pass partial data that still type-checks |
… 证据边界与执行链路
作者原文负责流程事实;流狐只索引当前章节、要点、文件与命令。
章节 -> Why shoehorn? → Install → Migration patterns → Large objects with few needed properties → as Type → fromPartial() → as unknown as Type → fromAny()
要点 -> Test code only. · Gather requirements · Install and migrate · shoehorn lets you pass partial data in tests while keeping TypeScript happy. · 1. Gather requirements - ask user: - What test files have as assertions causing problems?
文件/命令 -> shoehorn · as unknown as Type · as Type · fromPartial() · fromAny() · fromExact() · npm i @total-typescript/shoehorn · grep -r " as [A-Z]" --include=".test.ts" --include=".spec.ts"
内容 SHA-256 -> 6f3ca4fea691
设计思路
migrate-to-shoehorn是 mattpocock 的「测试代码as断言升级」专项 skill——把测试里as Type/as unknown as Type替换成@total-typescript/shoehorn的fromPartial()/fromAny(),让 TS 仍然开心、又不必虚构整份大对象。只在测试代码里用,永不进生产。为什么要换 shoehorn
as在测试里的痛点:asas unknown as Type双断言三个迁移模式
1. 大对象只关心少数属性
之前要塞 20 个伪属性才让 TS 闭嘴:
之后:
2.
as Type→fromPartial()直接替换。3.
as unknown as Type→fromAny()故意传错类型时用fromAny——保留 autocomplete。选哪个
fromPartial()fromAny()fromExact()工作流
as出了问题?是不是大对象只用几条字段?是不是要测错误路径?npm i @total-typescript/shoehorngrep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts"找断言点as Type→fromPartial()、as unknown as Type→fromAny()适合谁
as拖累的工程师不适合
@total-typescript/shoehorn绑定as——本 skill 明令仅限测试配套
tdd/test-driven-development(写测试母法)、improve-codebase-architecture(结构性改 testability)、request-refactor-plan(大批量重构 plan 出口)。