Score
9.1
/ 10
Installs
209K
Repo Stars
215.5K
Last Updated
5d ago
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 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
-
Gather requirements - ask user:
- What test files have
asassertions causing problems? - Are they dealing with large objects where only some properties matter?
- Do they need to pass intentionally wrong data for error testing?
- What test files have
-
Install and migrate:
- Install:
npm i @total-typescript/shoehorn - Find test files with
asassertions:grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts" - Replace
as TypewithfromPartial() - Replace
as unknown as TypewithfromAny() - Add imports from
@total-typescript/shoehorn - Run type check to verify
- Install: