migrate-to-shoehorn
작성자 mattpocockmigrate-to-shoehorn는 TypeScript 테스트 파일에서 안전하지 않은 `as`, `as unknown as` 캐스트를 @total-typescript/shoehorn의 `fromPartial()`와 `fromAny()`로 리팩터링할 때 유용한 스킬입니다. 테스트 전용 fixture 정리, 부분 데이터 처리, 더 안전한 negative test 마이그레이션에 적합합니다.
이 스킬은 78/100점으로, 안전하지 않은 `as` 단언을 `@total-typescript/shoehorn`로 옮겨야 하는 사용자에게는 충분히 탄탄한 디렉터리 항목입니다. 무엇을 위해 설치하는지와 어떤 워크플로를 지원하는지 빠르게 파악할 수 있지만, 완성형 마이그레이션 도구 패키지라기보다 문서 중심의 집중형 스킬에 가깝다는 점은 감안해야 합니다.
- frontmatter만 봐도 언제 써야 하는지 분명합니다. 사용자가 shoehorn, 테스트에서의 `as` 교체, 부분 테스트 데이터 등을 언급할 때 활용하도록 명확히 안내합니다.
- `fromPartial()`와 `fromAny()`에 대한 구체적인 전후 예시가 있어 바로 적용 가능한 마이그레이션 가이드를 제공합니다. 에이전트가 재사용할 수 있는 변환 패턴을 얻기 좋습니다.
- 설치 판단에 필요한 정보가 분명합니다. shoehorn가 왜 유용한지 설명하고, 설치 명령을 포함하며, 테스트 코드에서만 사용해야 한다는 점도 명시적으로 경고합니다.
- 범위가 좁습니다. `as` 단언을 `@total-typescript/shoehorn`로 바꾸는 테스트 코드 마이그레이션에만 초점이 있으며, 더 넓은 TypeScript 정리 작업까지 다루지는 않습니다.
- 저장소 차원의 지원은 가벼운 편입니다. 추가 스크립트, 참고 자료, 자동화가 제공되지 않으므로 코드베이스 전반의 변경은 여전히 에이전트가 수동으로 적용해야 합니다.
migrate-to-shoehorn 스킬 개요
migrate-to-shoehorn 스킬은 TypeScript 테스트 코드에서 깨지기 쉬운 as 단언을 걷어내고, 대신 @total-typescript/shoehorn로 리팩터링할 수 있게 도와줍니다. 특히 테스트 전반에 as Type 또는 as unknown as Type가 많이 쌓여 있고, 큰 객체 타입 때문에 테스트 준비 코드가 장황하고 의도를 흐리는 경우에 migrate-to-shoehorn가 가장 잘 맞습니다.
migrate-to-shoehorn가 필요한 상황
migrate-to-shoehorn는 “새 라이브러리 하나 배워보기”가 목적이 아니라, 전체 테스트 스위트를 갈아엎지 않고도 안전하지 않은 테스트 fixture를 정리하고 싶을 때 쓰는 스킬입니다. 초점은 아주 명확한 리팩터링 작업에 맞춰져 있습니다.
as Type를fromPartial()로 바꾸기as unknown as Type를fromAny()로 바꾸기- 테스트에서 큰 입력 객체를 흉내 내기 위해 넣던 불필요한 boilerplate 줄이기
어떤 사람이 이 스킬을 설치하면 좋은가
다음에 해당한다면 이 migrate-to-shoehorn skill은 꽤 잘 맞습니다.
- 캐스팅이 많은 TypeScript 테스트를 유지보수하고 있다
- 더 안전한 partial fixture가 필요하다
- 어떤 단언 패턴이 어떤 shoehorn helper로 대응되는지 판단이 필요하다
- 일반적인 TypeScript 조언이 아니라, 좁고 명확한 리팩터링을 에이전트가 직접 수행하거나 안내해 주길 원한다
도입 전에 가장 먼저 봐야 할 점
가장 중요한 판단 기준은 적용 범위입니다. 이 스킬은 명시적으로 테스트용이며, 프로덕션 코드를 위한 것이 아닙니다. 이 구분이 중요한 이유는, shoehorn은 테스트에서 일부러 불완전하거나 심지어 잘못된 데이터를 넣어 케이스를 만들 때 유용하지만, 그렇더라도 무작정 raw assertion을 쓰기보다 더 분명하고 의도적인 타이핑을 유지하게 해주기 때문입니다.
왜 일반적인 리팩터링 프롬프트 대신 migrate-to-shoehorn를 써야 하나
범용 프롬프트는 as를 기계적으로 제거하고, 그 캐스트가 왜 들어가 있었는지 의도를 놓치기 쉽습니다. migrate-to-shoehorn가 더 실용적인 이유는, 개발자가 실제 마이그레이션 과정에서 자주 마주치는 패턴에 맞춰져 있기 때문입니다.
- 큰 객체 타입에 대한 부분적인 테스트 입력
- negative test를 위해 일부러 잘못 넣는 데이터
- 테스트와 무관한 가짜 속성을 줄이고 싶은 경우
이렇게 범위를 좁혀 두면, 추측은 줄고 위험한 치환도 덜 생깁니다.
migrate-to-shoehorn 스킬 사용법
migrate-to-shoehorn 스킬 설치 맥락
프로젝트에서 기반 라이브러리를 사용하려면 먼저 설치하세요.
npm i @total-typescript/shoehorn
스킬을 skills-enabled 환경에 설치하는 경우에는, 사용하는 플랫폼의 일반적인 스킬 설치 흐름을 따르면 됩니다. 그런 다음 테스트 리팩터링 작업 중 migrate-to-shoehorn를 호출해 사용하세요.
먼저 읽어야 할 파일
가장 먼저 migrate-to-shoehorn 폴더의 SKILL.md를 보세요. 이 저장소에서는 이 파일이 사실상 단일 기준 문서이며, 스킬이 따르는 마이그레이션 패턴도 여기에 정리되어 있습니다.
권장 읽기 순서:
migrate-to-shoehorn/SKILL.md- 변경하려는 테스트 파일들
- 로컬 코드베이스에서 쓰이고 있는
as Type와as unknown as Type
스킬에 어떤 입력을 주면 좋은가
이 스킬은 다음 정보를 함께 줄 때 가장 잘 작동합니다.
- 현재 테스트 코드 조각
- 호출 대상 함수 또는 컴포넌트
- 알고 있다면 관련 타입 이름
- 테스트 데이터가 유효해야 하는지, 아니면 일부러 잘못된 데이터인지
- 일회성 수정이 필요한지, 반복 가능한 마이그레이션 패턴이 필요한지
이 맥락이 없더라도 에이전트가 fromPartial()이나 fromAny()를 제안할 수는 있지만, 잘못된 helper를 고를 가능성이 높아집니다.
요청할 핵심 migrate-to-shoehorn 마이그레이션 패턴
실전에서 자주 쓰는 migrate-to-shoehorn usage 패턴은 단순합니다.
as Type→ 보통fromPartial()as unknown as Type→ 보통fromAny()- 거대한 가짜 객체인데 실제로 몇 개 필드만 중요함 →
fromPartial()
이게 바로 이 스킬의 핵심 가치입니다. “이 테스트 캐스트들 좀 정리해줘” 같은 모호한 요청을, 일관된 리팩터링 방식으로 바꿔줍니다.
강한 migrate-to-shoehorn 프롬프트를 쓰는 방법
약한 프롬프트:
Replace
aswith shoehorn.
더 좋은 프롬프트:
Use the
migrate-to-shoehornskill to refactor this test file. Replace plainas Requestcasts withfromPartial()where the object is just a partial fixture. Replaceas unknown as RequestwithfromAny()only where the test intentionally passes invalid data. Keep the test behavior unchanged and add imports if needed.
이렇게 요청하면 에이전트가 의도, 경계, 판단 기준을 함께 받게 됩니다.
예시: partial fixture를 migrate-to-shoehorn로 전환
Before:
getUser({ body: { id: "123" } } as Request);
After:
import { fromPartial } from "@total-typescript/shoehorn";
getUser(fromPartial({ body: { id: "123" } }));
이 방식은 fixture가 구조적으로는 불완전하지만, 테스트 맥락에서는 개념적으로 유효한 데이터일 때 적합합니다.
예시: 의도적으로 잘못된 데이터를 migrate-to-shoehorn로 전환
Before:
getUser({ body: { id: 123 } } as unknown as Request);
After:
import { fromAny } from "@total-typescript/shoehorn";
getUser(fromAny({ body: { id: 123 } }));
이 방식은 validation이나 실패 경로를 검증하기 위해 테스트가 일부러 잘못된 데이터를 넘기는 경우에 사용하세요.
큰 규모 리팩터링에서 가장 안전한 workflow
저장소 전체에 적용하는 migrate-to-shoehorn guide가 필요하더라도, 모든 것을 한 번에 무차별적으로 바꾸지는 마세요. 더 안전한 workflow는 다음과 같습니다.
- 테스트 파일에서
as와as unknown as를 검색한다 - 각 캐스트를 partial-valid와 intentionally-invalid로 분류한다
- 먼저 테스트 폴더 하나만 마이그레이션한다
- 테스트와 typecheck를 돌린다
- import 스타일과 helper 선택 기준을 통일한다
- 그다음 나머지 스위트로 확장한다
이 순서를 따르면, 진짜 negative test용 캐스트와 일반 fixture 정리를 뒤섞는 일을 피할 수 있습니다.
결과 품질을 높이는 실전 팁
에이전트에게 다음 요소는 유지하라고 분명히 요청하세요.
- 기존 테스트 이름과 assertion
- invalid-input 테스트가 갖는 의미적 의도
- 불필요하게 다 펼친 가짜 객체 대신 최소 fixture 형태
- 여러 helper를 쓸 때 import 중복 정리
또한 가능한 가장 작은 fixture를 우선하라고 명시하면 좋습니다. 대체로 그쪽이 더 깔끔한 shoehorn 리팩터링으로 이어집니다.
migrate-to-shoehorn가 맞지 않는 경우
실제 문제가 프로덕션 타입 안정성, 도메인 모델링, API 계약 정확성이라면 migrate-to-shoehorn for Refactoring은 적절한 도구가 아닙니다. 이 스킬은 타입 전반을 “고치는” 용도가 아니라, 테스트 리팩터링에 초점을 맞춘 보조 도구입니다.
migrate-to-shoehorn 스킬 FAQ
migrate-to-shoehorn는 테스트에만 쓰는 건가요?
네. 이것이 가장 중요한 경계입니다. 이 스킬은 프로덕션 타이핑 패턴이 아니라, 테스트 작성 편의성과 테스트 의도를 중심으로 설계되어 있습니다.
테스트가 이미 통과하고 있어도 shoehorn가 필요한가요?
반드시 그렇지는 않습니다. 현재 테스트가 읽기 어렵고, 장황한 가짜 객체가 많고, 의도를 숨기는 unsafe cast에 의존하고 있다면 migrate-to-shoehorn를 도입할 가치가 있습니다. 반대로 테스트 셋업이 이미 충분히 깔끔하다면, 마이그레이션 비용에 비해 얻는 이점이 크지 않을 수 있습니다.
fromPartial과 fromAny의 차이는 무엇인가요?
fromPartial()은 불완전하더라도 전반적으로는 말이 되는 fixture 데이터에 적합합니다.
fromAny()는 일부러 잘못된 데이터를 넣는 경우에 적합하며, 테스트가 나쁜 런타임 입력을 흉내 내기 위해 더 엄격한 타이핑을 우회해야 할 때 씁니다.
이 구분이야말로, 단순한 “assertion 제거” 프롬프트보다 이 스킬을 쓰는 핵심 이유 중 하나입니다.
migrate-to-shoehorn는 초보자도 쓸 수 있나요?
네, 기본적인 TypeScript 테스트를 이해하고 있다면 충분히 사용할 수 있습니다. 스킬 범위가 작고, 마이그레이션 규칙도 따라가기 쉽습니다. 초보자에게 가장 흔한 위험은 테스트 바깥에서도 shoehorn를 과하게 쓰는 것입니다.
저장소 전체 마이그레이션에도 이 스킬을 쓸 수 있나요?
가능합니다. 다만 범주별로 나눠 검토하는 경우에만 그렇습니다. 대규모 마이그레이션에서 가장 흔한 실패는 모든 캐스트를 같은 것으로 취급하는 데 있습니다. 어떤 것은 partial fixture이고, 어떤 것은 의도적으로 깨진 payload이며, 또 어떤 것은 프로덕션 코드에 속해 있어서 이 패턴으로 옮기면 안 될 수도 있습니다.
일반 프롬프트보다 이게 더 낫나요?
대체로 그렇습니다. 특히 작업 목표가 정확히 “테스트 assertion을 shoehorn로 옮기기”일 때 그렇습니다. 일반 프롬프트도 라이브러리를 알고 있을 수는 있지만, 예전 캐스트 스타일을 올바른 helper로 일관되게 대응시키고 싶다면 migrate-to-shoehorn usage 쪽이 더 낫습니다.
migrate-to-shoehorn 스킬을 더 잘 활용하는 방법
코드만 주지 말고 테스트 의도도 함께 전달하기
migrate-to-shoehorn 결과를 가장 빠르게 개선하는 방법은, 각 테스트가 무엇을 검증하는지 명확히 알려주는 것입니다.
- 부분적인 setup으로 happy path 동작을 보는 테스트인지
- 일부러 잘못된 입력으로 validation failure를 보는 테스트인지
- 몇 개 필드만 있으면 되는 edge case인지
이 한 가지 정보만으로도 fromPartial()와 fromAny() 중 무엇을 쓸지 결정되는 경우가 많습니다.
처음부터 test-only 파일이라고 표시하기
파일 안에 helper 코드와 프로덕션 코드가 섞여 있다면 그 사실을 먼저 알려주세요. 에이전트에게 아래처럼 명시하면 이 스킬은 훨씬 안전해집니다.
Only apply migrate-to-shoehorn changes inside test files and test fixtures.
이렇게 해야 테스트가 아닌 경로로 변경이 번지는 일을 막을 수 있습니다.
변경 전에 cast 목록부터 분류해 달라고 요청하기
복잡한 테스트 스위트라면, 바로 수정에 들어가기 전에 먼저 이렇게 시작하세요.
Using the
migrate-to-shoehorn skill, classify each cast in this file asfromPartial,fromAny, or leave unchanged, then explain why.
이처럼 먼저 검토하고 나중에 수정하는 단계가 있으면, 실제 rewrite 전에 예외 케이스를 더 잘 걸러낼 수 있습니다.
타입 추론이 애매하면 주변 타입 정보까지 제공하기
코드 조각만으로 기대 타입이 드러나지 않는다면, 함수 시그니처나 관련 타입 정의를 함께 주세요. 타입 맥락이 분명할수록 import 선택이 정확해지고, 어색한 rewrite도 줄어듭니다.
이런 흔한 실패 패턴을 주의하기
migrate-to-shoehorn install과 도입 과정에서 자주 생기는 문제는 다음과 같습니다.
- 프로덕션 코드에 shoehorn를 사용하는 것
- 일부러 잘못된 데이터를
fromPartial()로 바꾸는 것 - fixture 객체를 단순화하지 않고 오히려 더 키우는 것
- 타입을 “정리한다”면서 테스트 의미까지 바꾸는 것
이건 라이브러리 자체의 문제가 아니라, 프롬프트와 리뷰 과정의 문제입니다.
첫 결과물에서 한 번 더 다듬기
첫 번째 결과를 받은 뒤에는 다음과 같은 2차 정리를 요청해 보세요.
- 각 fixture를 테스트에 필요한 필드만 남기도록 최소화하기
- import 정리 및 통합하기
- 남겨둬야 하는 캐스트가 있다면 이유 설명하기
- 유효한 partial 데이터와 invalid test 데이터를 분리하기
이 과정을 거치면 단순 마이그레이션에서 끝나지 않고, 장기적으로 더 깔끔한 테스트 패턴까지 정리할 수 있습니다.
