mcpField
M
migrate-to-shoehorn

migrate-to-shoehorn

github.com/akillnessTesting & quality53240 installsUpdated today
Repository

About migrate-to-shoehorn

migrate-to-shoehorn is an agent skill for replacing TypeScript `as` assertions in test files with `@total-typescript/shoehorn` functions. It guides developers through choosing helpers for partial, intentionally invalid, or complete test data, then checking types.

Key features

  1. 01Replace `as` in tests
  2. 02Use `fromPartial()` for partial data
  3. 03Use `fromAny()` for invalid data
  4. 04Use `fromExact()` for complete objects
  5. 05Run a type check after migration

Use cases

  1. 01Migrate test files with `as` assertions
  2. 02Create tests using partial objects
  3. 03Test errors with intentionally wrong data

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/akillness/jeo-skills --skill migrate-to-shoehorn

After installing, type/migrate-to-shoehornin Claude Code to confirm it loaded.

Details

From the project README

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.

This skill is imported from mattpocock/skills (MIT) and is model-invoked upstream.

When to use this skill

  • 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.

Instructions

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
FunctionUse 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

Examples

  • Apply this skill to one narrow scope first, confirm the output matches the shape described above, then widen to the full task.
  • When a step needs a fact from the repository or the environment, look it up instead of asking the user for it.

Best practices

  • Keep the upstream procedure intact; record deviations explicitly instead of silently improvising.
  • Stop and hand control back to the user at every decision point this skill marks as theirs.
  • Prefer small reversible changes, and state assumptions rather than burying them.

References

  • Upstream skill: mattpocock/skills skills/misc/migrate-to-shoehorn/SKILL.md (commit 3cca18b, MIT)
  • Project standards: .agent-skills/skill-standardization/SKILL.md
  • Validator script: .agent-skills/skill-standardization/scripts/validate_skill.sh

Comments

Markdown supported