← marketplace
engineerslibrarysha:d5063ddcd9478e86manual
mp-migrate-to-shoehorn
Use when refactoring TypeScript TEST files away from `as` type assertions to @total-typescript/shoehorn — fromPartial() for partial type-safe data, fromAny() for intentionally-wrong inputs.
source: https://github.com/mattpocock/skills/blob/main/skills/misc/migrate-to-shoehorn/SKILL.md ↗mattpocock/skills· ★ 76k
One-line install
curl --create-dirs -fsSL https://skillmake.xyz/i/mp-migrate-to-shoehorn -o ~/.claude/skills/mp-migrate-to-shoehorn/SKILL.md
The hash above pins this exact content. The file we serve at /api/marketplace/mp-migrate-to-shoehorn-d5063ddc/raw always matches sha:d5063ddcd9478e86.
4,324 chars · ~1,081 tokens
--- name: mp-migrate-to-shoehorn description: Use when refactoring TypeScript TEST files away from `as` type assertions to @total-typescript/shoehorn — fromPartial() for partial type-safe data, fromAny() for intentionally-wrong inputs. source: https://github.com/mattpocock/skills/blob/main/skills/misc/migrate-to-shoehorn/SKILL.md generated: 2026-05-12T18:05:10.811Z category: library audience: engineers --- ## When to use - Test code is full of `as Request`, `as User`, `as unknown as X` and you want type-safe partial fixtures instead - Passing only a few properties from a large object type into a function-under-test - Deliberately injecting wrong-shaped data to test error paths, without losing autocomplete - Auditing test files for `as` assertions across a codebase with a single grep ## Key concepts ### shoehorn is tests-only @total-typescript/shoehorn is for TEST code. Never use it in production code — you lose the type safety that justified writing TypeScript in the first place. Matt is explicit about this. ### why `as` is a smell in tests `as Type` forces TypeScript to trust you, must specify target type manually, and the double-as pattern (`as unknown as Type`) for intentionally wrong data is ugly. Shoehorn keeps the IDE helpful while letting you pass partials. ### fromPartial() Pass partial data that still type-checks against the full type. Use for the common case: you only care about a few properties of a large input. ### fromAny() Pass intentionally wrong data — e.g. `{ body: { id: 123 } }` where the type wants `id: string`. Keeps autocomplete on the surrounding object while waving through the deliberately-wrong field. Replaces `as unknown as Type`. ### fromExact() Force a full object (every property must be present). Useful as a step before refactoring to fromPartial later — you can ratchet the test from 'must be exact' to 'partial is fine' as the type stabilises. ## API reference ``` Install ``` Single dev dependency. ``` npm i @total-typescript/shoehorn ``` ``` fromPartial — replace `as Type` ``` Most common migration. Pass only what the test cares about. ``` import { fromPartial } from "@total-typescript/shoehorn"; it("gets user by id", () => { getUser( fromPartial({ body: { id: "123" }, }), ); }); ``` ``` fromAny — replace `as unknown as Type` ``` When you're feeding the function deliberately-wrong data to test error handling. ``` import { fromAny } from "@total-typescript/shoehorn"; getUser(fromAny({ body: { id: 123 } })); ``` ``` Migration grep ``` Find every TypeScript test file using `as` type assertions in one go. ``` grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts" ``` ``` Workflow checklist ``` Steps to run in order. Type-check at the end catches mismatched migrations. ``` [ ] Install: npm i @total-typescript/shoehorn [ ] Find test files with `as` assertions (grep above) [ ] Replace `as Type` → fromPartial() [ ] Replace `as unknown as Type` → fromAny() [ ] Add imports from @total-typescript/shoehorn [ ] Run tsc --noEmit to verify ``` ## Gotchas - TESTS ONLY. Don't sneak shoehorn into production code — it bypasses the type system on purpose. - `fromPartial` requires the type to be inferrable from the call site. If the function signature uses generics, you may need to annotate. - `fromAny` keeps autocomplete on the SURROUNDING object, not on the deliberately-wrong field. The wrong field is still 'any'. - If a test was passing because `as` silenced a real bug, the shoehorn migration will surface it — that's a win, not a regression. - Watch for `as const` — that's a different construct (literal type assertion) and should NOT be migrated to shoehorn. - After migration, run the full tsc --noEmit, not just per-file. Type errors can propagate from helpers that consumed the old `as` shapes. - fromExact is rarely the right starting point — prefer fromPartial unless the test needs exhaustive shape verification. - If you're on a non-TS test framework or your tests live alongside production code, scoping shoehorn correctly takes more care — keep the dependency in devDependencies. --- Generated by SkillMake from https://github.com/mattpocock/skills/blob/main/skills/misc/migrate-to-shoehorn/SKILL.md on 2026-05-12T18:05:10.811Z. Verify against source before relying on details.
File: ~/.claude/skills/mp-migrate-to-shoehorn/SKILL.md