Skill Tracer
Skills › Skills For Real Engineers › migrate-to-shoehorn

migrate-to-shoehorn

skill · 118 lines · MIT · skills/misc/migrate-to-shoehorn/SKILL.md

The facts

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

The description the agent reads to decide when to use it.

From its settingsline 3

When it starts

The agent picks this skill when the conversation is about cleaning up TypeScript test files, specifically replacing `as` type assertions with the @total-typescript/shoehorn library or passing partial/intentionally wrong test data. It is triggered by the user naming shoehorn, complaining about `as` casts in tests, or needing partial test fixtures.

Things a person might say (the model's guesses)

  • “Can you get rid of all the `as` casts in our test files?”
  • “I keep having to fake entire objects in my tests — is there something like shoehorn for this?”
  • “How do I pass partial test data without TypeScript complaining?”

A model's summary of when it is used.

A model's reading

Licence

MIT, from LICENSE

The terms its author shares it under, which let it be shown here.

From the repositorylicence text
Other files in this skill (1) Close

The text

Open on GitHub
1---
2name: migrate-to-shoehorn
3description: 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.
4---
5
6# Migrate to Shoehorn
7

Migrate to Shoehorn

Raw lines 1 to 7
8## Why shoehorn?
9
10`shoehorn` lets you pass partial data in tests while keeping TypeScript happy. It replaces `as` assertions with type-safe alternatives.
12**Test code only.** Never use shoehorn in production code.
14Problems with `as` in tests:
16- Trained not to use it
17- Must manually specify target type
18- Double-as (`as unknown as Type`) for intentionally wrong data

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
Raw lines 8 to 19
20## Install
22```bash
23npm i @total-typescript/shoehorn
24```

Install

npm i @total-typescript/shoehorn
Raw lines 20 to 25
26## Migration patterns

Migration patterns

Raw lines 26 to 27
28### Large objects with few needed properties
30Before:
32```ts
33type Request = {
34 body: { id: string };
35 headers: Record<string, string>;
36 cookies: Record<string, string>;
37 // ...20 more properties
38};
40it("gets user by id", () => {
41 // Only care about body.id but must fake entire Request
42 getUser({
43 body: { id: "123" },
44 headers: {},
45 cookies: {},
46 // ...fake all 20 properties
47 });
48});
49```
51After:
53```ts
54import { fromPartial } from "@total-typescript/shoehorn";
56it("gets user by id", () => {
57 getUser(
58 fromPartial({
59 body: { id: "123" },
60 }),
61 );
62});
63```

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" },
    }),
  );
});
Raw lines 28 to 64
65### `as Type` → `fromPartial()`
67Before:
69```ts
70getUser({ body: { id: "123" } } as Request);
71```
73After:
75```ts
76import { fromPartial } from "@total-typescript/shoehorn";
78getUser(fromPartial({ body: { id: "123" } }));
79```

as Type → fromPartial()

Before:

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

After:

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

getUser(fromPartial({ body: { id: "123" } }));
Raw lines 65 to 80
81### `as unknown as Type` → `fromAny()`
83Before:
85```ts
86getUser({ body: { id: 123 } } as unknown as Request); // wrong type on purpose
87```
89After:
91```ts
92import { fromAny } from "@total-typescript/shoehorn";
94getUser(fromAny({ body: { id: 123 } }));
95```

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 } }));
Raw lines 81 to 96
97## When to use each
99| Function | Use case |
100| --------------- | -------------------------------------------------- |
101| `fromPartial()` | Pass partial data that still type-checks |
102| `fromAny()` | Pass intentionally wrong data (keeps autocomplete) |
103| `fromExact()` | Force full object (swap with fromPartial later) |

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)
Raw lines 97 to 104
105## Workflow
1071. **Gather requirements** - ask user:
108 - What test files have `as` assertions causing problems?
109 - Are they dealing with large objects where only some properties matter?
110 - Do they need to pass intentionally wrong data for error testing?
1122. **Install and migrate**:
113 - [ ] Install: `npm i @total-typescript/shoehorn`
114 - [ ] Find test files with `as` assertions: `grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts"`
115 - [ ] Replace `as Type` with `fromPartial()`
116 - [ ] Replace `as unknown as Type` with `fromAny()`
117 - [ ] Add imports from `@total-typescript/shoehorn`
118 - [ ] Run type check to verify

Workflow

  1. Gather requirements - ask user:
  2. What test files have as assertions causing problems?
  3. Are they dealing with large objects where only some properties matter?
  4. Do they need to pass intentionally wrong data for error testing?
  1. Install and migrate:
  2. [ ] Install: npm i @total-typescript/shoehorn
  3. [ ] Find test files with as assertions: grep -r " as [A-Z]" --include="*.test.ts" --include="*.spec.ts"
  4. [ ] Replace as Type with fromPartial()
  5. [ ] Replace as unknown as Type with fromAny()
  6. [ ] Add imports from @total-typescript/shoehorn
  7. [ ] Run type check to verify
Raw lines 105 to 118

From mattpocock/skills at 4ae2317, 2026-10-31. Skills read by DeepSeek V4.1 Flash on 2026-11-04. Summary and techniques by Claude Opus 5.5 on 2026-11-06.