Matt Pocock 杂项 - migrate-to-shoehorn

Model: qwen-max | ¥0.15/call
工程方法论GPT-4.1工程实践migrateto

migrate-to-shoehorn:mattpocock/skills 方法论: misc/migrate-to-shoehorn,适用于工程实践、代码质量与开发流程优化。

Calls: 1

Skill Documentation

Matt Pocock 杂项 - migrate-to-shoehorn

摘要

migrate-to-shoehorn:mattpocock/skills 方法论: misc/migrate-to-shoehorn,适用于工程实践、代码质量与开发流程优化。

> 来源: mattpocock/skills (141k stars) — Total TypeScript 创始人 Matt Pocock

> 类目: 杂项

> 原文件: skills/misc/migrate-to-shoehorn/SKILL.md

> 模型推荐: gpt-4.1 (代码工程)

这个 skill 是干嘛的

Matt Pocock (Total TypeScript, 141k stars) 沉淀下来的"日常代码工程动作"skill 模板。

每一个对应一个具体动作(代码评审 / TDD / 重构 / 文档对齐 / 任务交接),不是工具,是"该怎么干这件事"的工作流模板。

michael 强调"skill 要有相应的指导功能,指导用户使用",所以这里加了下面两节让 Agent 和用户对接。

---

🤖 Agent 使用说明

1. 接到任务后先按这个 skill 的检查清单走一遍

2. 清单里如果出现"先做 X 才能做 Y"的红线 → 必须先完成 X

3. 跑完清单后开始动手(改代码 / 写文档 / 评审)

4. 完工前用 `verification-before-completion`(superpowers) 或 `verification` 类 step 自检

5. 任务量大时考虑用 `dispatching-parallel-agents`(superpowers) 或 `wayfinder`(mattpocock) 拆解

👤 用户需要做什么?

1. 告诉 Agent 你要做什么(一句话即可)

2. Agent 跑 skill 清单时不要打断 — 它可能在收集上下文

3. 如果 Agent 主动问你"代码评审要不要安排一个 reviewer"等决策点 → 直接回答

4. 完工后让 Agent 跑一遍自检再交回

5. 整个过程 Agent 自动化,不需要手工介入

---

原 skill 内容(mattpocock/skills/misc/migrate-to-shoehorn/SKILL.md)

---

name: migrate-to-shoehorn

description: Migrate test files from `as` type assertions to @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` 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

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

1. **Gather requirements** - ask user:

2. **Install and migrate**:

FAQ

👤 用户需要做什么?

1. 告诉 Agent 你要做什么(一句话即可)

2. Agent 跑 skill 清单时不要打断 — 它可能在收集上下文

3. 如果 Agent 主动问你"代码评审要不要安排一个 reviewer"等决策点 → 直接回答

4. 完工后让 Agent 跑一遍自检再交回

5. 整个过程 Agent 自动化,不需要手工介入

---

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
Do they need to pass intentionally wrong data for error testing?

2. **Install and migrate**:

  • [ ] Install: `npm i @total-typescript/shoehorn`
  • [ ] Find test files with `as` assertions: `grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts"`
  • [ ] Replace `as Type` with `fromPartial()`
  • [ ] Replace `as unknown as Type` with `fromAny()`
  • [ ] Add imports from `@total-typescript/shoehorn`
  • [ ] Run type check to verify