Back to skills

Agent Skill

Migrate To Shoehorn

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.

MattpocockTestingShell

209K installs

mattpocock/skills

by Mattpocock

Score

9.1

/ 10

Installs

209K

Repo Stars

215.5K

Last Updated

5d ago

Fresh

Quality Ratio

93%

Description

Verified

Language

Shell

First Published

Feb 2026

Summary

The Migrate To Shoehorn agent skill refactors TypeScript test files by replacing problematic `as` type assertions with type-safe utilities from `@total-typescript/shoehorn`, enabling cleaner and more robust tests with partial or intentionally incorrect data. This agent skill is invaluable for TypeScript developers writing unit and integration tests who are accustomed to using `as` for type assertions but seek a more maintainable and type-safe approach. It is an emerging or highly specialized skill with limited adoption so far, catering to a specific testing paradigm within the TypeScript ecosystem. Practically, it guides the agent to migrate `as Type` assertions to `fromPartial()` for providing partial test data, and `as unknown as Type` to `fromAny()` for testing with deliberately incorrect types. It also instructs the agent on how to identify relevant test files via `grep` and manage the installation of the `@total-typescript/shoehorn` library to ensure type-checking integrity. This skill is specifically scoped to improving TypeScript test code and should not be applied to production codebases.

Skill Definition

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 TypefromPartial()

Before:

getUser({ body: { id: "123" } } as Request);

After:

import { fromPartial } from "@total-typescript/shoehorn";

getUser(fromPartial({ body: { id: "123" } }));

as unknown as TypefromAny()

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

How to Use

Use in O-mega

Claude Code

npx skills add mattpocock/skills migrate-to-shoehorn