migrate-to-shoehorn
vinvcn/mattpocock-skills-zh-cn
Replace unsafe `as` type assertions in tests with type-safe shoehorn alternatives.
What is migrate-to-shoehorn?
Migrate test files from TypeScript `as` type assertions to @total-typescript/shoehorn for safer, more maintainable partial test data. Use this when you want to pass incomplete objects to test functions while preserving type safety and avoiding double-as patterns.
- Replace `as Type` assertions with `fromPartial()` for type-checked partial data
- Replace `as unknown as Type` with `fromAny()` for intentionally wrong test data
- Eliminate manual faking of unused properties in large test objects
- Maintain TypeScript autocomplete and type checking in test code
- Provide a structured workflow to find and migrate existing assertions
How to install migrate-to-shoehorn
npx skills add https://github.com/vinvcn/mattpocock-skills-zh-cn --skill migrate-to-shoehorn- npm i @total-typescript/shoehorn
How to use migrate-to-shoehorn
- 1.Identify test files containing `as` type assertions using grep or manual search
- 2.Replace `as Type` patterns with `fromPartial({ /* partial data */ })`
- 3.Replace `as unknown as Type` patterns with `fromAny({ /* wrong data */ })`
- 4.Add import statement: `import { fromPartial, fromAny } from '@total-typescript/shoehorn'`
- 5.Run TypeScript type check to verify migrations are correct
Use cases
- Migrating a test suite that uses `as` assertions to pass partial request/response objects
- Testing error paths by passing intentionally incorrect data types while keeping autocomplete
- Reducing boilerplate in tests for large objects where only a few properties matter
- Replacing double-as patterns (`as unknown as Type`) with clearer intent via `fromAny()`
- Ensuring type safety in test fixtures without manually constructing complete mock objects
- TypeScript developers writing unit tests
- Teams maintaining large test suites with type assertion debt
- QA engineers or developers testing error handling paths
- Projects using strict type checking that want safer test patterns
migrate-to-shoehorn FAQ
No. Shoehorn is designed only for test code. Never use it in production.
Use `fromPartial()` when passing partial data that still type-checks correctly. Use `fromAny()` when you intentionally pass wrong types (e.g., testing error handling) while preserving autocomplete.
No. Unlike `as Type`, shoehorn infers the type from context, reducing boilerplate.
Use: `grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts"` to locate them.
Use `fromExact()` to enforce the full object shape, then migrate to `fromPartial()` later if needed.
Full instructions (SKILL.md)
Source of truth, from vinvcn/mattpocock-skills-zh-cn.
name: migrate-to-shoehorn
description: 将 test files 从 as type assertions 迁移到 @total-typescript/shoehorn。Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
Migrate to Shoehorn
Why shoehorn?
shoehorn 允许你在 tests 中传入 partial data,同时保持 TypeScript 满意。它用 type-safe alternatives 替换 as assertions。
只用于 test code。 永远不要在 production code 中使用 shoehorn。
Tests 中 as 的问题:
- 会训练人忽略类型安全
- 必须手动指定 target type
- 对故意错误的数据需要 double-as(
as unknown as Type)
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() | 传入仍能 type-check 的 partial data |
fromAny() | 传入故意错误的数据(保留 autocomplete) |
fromExact() | 强制 full object(之后可换成 fromPartial) |
Workflow
-
Gather requirements — 询问用户:
- 哪些 test files 中的
asassertions 造成问题? - 是否在处理大型 objects,但只关心部分 properties?
- 是否需要传入故意错误的数据来测试 error paths?
- 哪些 test files 中的
-
Install and migrate:
- Install:
npm i @total-typescript/shoehorn - 查找 test files 中的
asassertions:grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts" - 用
fromPartial()替换as Type - 用
fromAny()替换as unknown as Type - 添加来自
@total-typescript/shoehorn的 imports - 运行 type check 验证
- Install:
Related skills
More from vinvcn/mattpocock-skills-zh-cn and the wider catalog.

obsidian-vault
在 Obsidian vault 中使用 wikilinks 和 index notes 搜索、创建并管理 notes。Use when user wants to find, create, or organize notes in Obsidian.

prototype
Build throwaway prototypes to validate designs and state models before committing to production code.

qa
交互式 QA session,用户以对话方式报告 bugs 或 issues,agent 创建 GitHub issues。后台探索 codebase 以获取 context 和 domain language。Use when user wants to report bugs, do QA, file issues conversationally, or mentions "QA session".

request-refactor-plan
通过 user interview 创建带 tiny commits 的详细 refactor plan,然后 file as a GitHub issue。Use when user wants to plan a refactor, create a refactoring RFC, or break a refactor into safe incremental steps.

scaffold-exercises
Scaffold exercise directory structures with sections, problems, solutions, and explainers that pass linting.

setup-matt-pocock-skills
Configure issue tracker, triage labels, and domain docs for engineering agent skills.