Skip to content
Development
Skill

/migrate-to-shoehorn

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.

From plugin
skills
309k31 skills

Claude Code

$ npx -y skills add mattpocock/skills --skill migrate-to-shoehorn --agent claude-code

SKILL.md

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:

  • 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

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

  • What test files have `as` assertions causing problems?
  • Are they dealing with large objects where only some properties matter?
  • 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
Read more
@mattpocock
Ships withskills

My agent skills that I use every day to do real engineering - not vibe coding. Developing real applications is hard. Approaches like GSD, BMAD, and Spec-Kit try to help by owning the process.

Stars on GitHub

Momentum

stars in total
308.6k
Star history of mattpocock/skills on GitHub, a chart by star-history.com

Other skills on skills.

ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

@mattpocock@mattpocockInstall Skill
code-review

code-review

Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes: Standards (does the code follow this…

@mattpocock@mattpocockInstall Skill
codebase-design

codebase-design

Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening…

@mattpocock@mattpocockInstall Skill
diagnosing-bugs

diagnosing-bugs

Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something…

@mattpocock@mattpocockInstall Skill
domain-modeling

domain-modeling

Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or…

@mattpocock@mattpocockInstall Skill
grill-with-docs

grill-with-docs

A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.

@mattpocock@mattpocockInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react3d252k
@facebook@facebookInstall Skill
act-on-feedback

act-on-feedback

Act on user feedback attached to the current session. Use when the user submits feedback on the session's changes via the Submit…

vscode2d195k
@microsoft@microsoftInstall Skill

Questions about migrate-to-shoehorn.

Which coding agents can use migrate-to-shoehorn?
migrate-to-shoehorn installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.