August 29, 2026 • ☕️☕️ 12 min read
import { Project } from "ts-morph";
const project = new Project({ tsConfigFilePath: "./tsconfig.json" });
const file = project.getSourceFileOrThrow("src/user.ts");
// 클래스에 메서드 추가
file.getClassOrThrow("User").addMethod({
name: "getFullName",
returnType: "string",
statements: "return `${this.first} ${this.last}`;",
});
await project.save(); // 실제 파일에 반영Babel이나 jscodeshift와 비교하면, ts-morph는 타입 정보에 접근할 수 있다는 게 가장 큰 차이. 심볼을 따라가서 “이 변수의 실제 타입이 뭔지”, “이 함수가 어디서 호출되는지”를 알 수 있어서 타입 기반 리팩터링에 강하다. 대신 tsconfig 전체를 로드하므로 큰 프로젝트에선 느릴 수 있다.
브라우저에서 .m3u8(HLS) 영상을 재생하게 해주는 라이브러리. Safari 말고는 HLS를 네이티브로 못 틀어서 필요하다.
const hls = new Hls();
hls.loadSource('https://example.com/playlist.m3u8');
hls.attachMedia(video); // <video> 엘리먼트에 연결
video.play();useFieldArray 와 swapuseFieldArray
배열 형태의 동적 필드를 다루는 훅. control과 name을 넘기면 fields와 조작 메서드(append, remove, swap, move 등)를 반환한다.
const { fields, swap } = useFieldArray({ control, name: "items" });
{fields.map((field, index) => (
<div key={field.id}> {/* index 말고 field.id 필수 */}
<input {...register(`items.${index}.name`)} />
</div>
))}swap(a, b)
두 인덱스의 항목을 서로 교환한다.
<button type="button" onClick={() => swap(index, index - 1)}>위로</button>[A,B,C,D] 기준으로 swap(0,2) → [C,B,A,D], move(0,2) → [B,C,A,D]. 인접 이동은 swap, 드래그앤드롭은 move.
Ref https://react-hook-form.com/docs/usefieldarray
리터럴 타입 유지와 타입 검사를 동시에 얻기 위한 TypeScript 패턴이다.
as const 단독
값을 가능한 한 좁은 리터럴 타입으로 만든다.
const config = {
mode: "dark",
retries: 3,
} as const;
// 타입: { readonly mode: "dark"; readonly retries: 3 }문제는 이렇게 하면 타입 검사를 못 받는다. mode에 오타를 내거나 허용되지 않는 값을 넣어도 에러가 안 난다.
satisfies T 단독
값이 특정 타입 T를 만족하는지 검사하되, 추론된 타입은 넓어질 수 있다.
type Config = { mode: "dark" | "light"; retries: number };
const config = {
mode: "dark",
retries: 3,
} satisfies Config;
// 타입: { mode: string; retries: number } 로 넓어짐 (또는 리터럴 유지 안 됨)as const satisfies T 결합
둘을 합치면 — 타입 검사도 받으면서, 추론 결과는 여전히 좁은 리터럴 타입을 유지한다.
type Config = { mode: "dark" | "light"; retries: number };
const config = {
mode: "dark",
retries: 3,
} as const satisfies Config;
// 타입 검사: mode가 "dark" | "light"에 속하는지 체크됨 ✅
// 추론된 타입: { readonly mode: "dark"; readonly retries: 3 } (좁게 유지됨)언제 유용한지?
type Route = { path: string; method: "GET" | "POST" };
const routes = {
home: { path: "/", method: "GET" },
submit: { path: "/submit", method: "POST" },
} as const satisfies Record<string, Route>;
routes.home.method; // 타입: "GET" (넓은 string이 아님!)satisfies가 없으면: 오타(“get” 등)나 허용 안 되는 값을 넣어도 컴파일러가 못 잡음as const가 없으면: routes.home.method의 타입이 “GET” | “POST”로 넓어져서, 특정 라우트에서 정확히 어떤 값인지 알 수 없음모든 일에 Fable 5 쓰면서 토큰 살살 태우기보단, 일상적인 업무들에는 Opus를 활용하는 것이 나아 보인다.
점점 모델 간의 우열 비교는 의미 없는 일이 될까?
Ref https://yozm.wishket.com/magazine/detail/3867/
오해 1: 개발자는 대부분의 시간을 코드 작성에 쓴다 -> 소프트웨어 엔지니어링은 코드 작성뿐 아니라 설계, 회의, 스탠드업, 계획, 코드 검토 등 개인·협업 활동으로 구성됨
오해 2: 코드 작성이 병목이다 -> 편집기에서 타이핑하는 시간이 약 15%라면 AI가 코딩을 2배 빠르게 해도 전체 생산성은 이론상 15% 미만으로 향상되며, 나머지 85%의 업무는 영향을 받지 않음
오해 3: AI가 작성한 코드 줄 수가 가장 좋은 영향 지표다 -> 소프트웨어 조직의 목표는 코드량 극대화가 아니라 안전하고 유지보수 가능하며 품질 높은 소프트웨어를 제공하는 것임
오해 4: AI는 모든 작업과 엔지니어에게 똑같이 도움 된다 -> 효과는 작업 특성, 개발자 경험, 코드베이스 친숙도, 자신감, 프롬프트 작성 역량이 함께 결정하므로 보편적인 성공 공식은 없음
오해 5: AI가 개인 개발자를 10배 개발자로 만든다 -> 개발자 간 성과 차이의 상당 부분은 개인의 고정된 능력보다 수행하는 작업에서 비롯됨
오해 6: AI를 제대로 활용하는 것은 각 개발자의 책임이다 -> 개발자가 더 큰 영향을 낼 수 있도록 조직 수준에서 소프트웨어 엔지니어링 시스템과 프로세스, 업무 환경을 다시 설계해야 함
오해 7: 성능이 좋은 AI 도구는 자동으로 채택된다 -> 다수는 직접 코드를 작성할 때보다 AI 결과를 디버깅하는 데 더 많은 시간을 쓴다고 답했으며, 이는 생산성 향상을 약화하고 인지 부하를 늘림
오해 8: 생성형 AI가 있으면 대기업도 스타트업 속도로 혁신할 수 있다 -> 대기업은 AI 모델이 접하지 못한 독점 도구와 레거시 코드베이스에 의존함
Ref https://news.hada.io/topic?id=32175&ref=surfit.io
클로드 헤드리스 모드: claude -p
클로드 채널
다른 서비스와 클로드 세션을 대화시키는 데 유용해 보인다.
Ref https://yozm.wishket.com/magazine/detail/3868/
AI 시대에도 개발과 유지보수에는 사람이 필연적으로 관여하게 된다.
엣지 케이스, 명시적인 버그들은 AI가 더 많이, 빠르게 잡아낼 수 있겠지만 모든 시스템의 기반을 이루고 있는 히스토리나 비즈니스 로직은 다 드러나지 않기에, 코드 리뷰는 여전히 꼭 학습해야 하는 기술인 것 같다.
Ref https://news.hada.io/topic?id=32417
커서를 인수한 스페이스X의 고공행진..! 🚀
오픈AI-앤트로픽-구글의 AI Top 3 라인 대열에 합류하게 될지, 궁금하다.
Ref https://yozm.wishket.com/magazine/detail/3898/
머릿속으로만 생각할 때는 이해했다고 착각하기 쉽지만, 실제 문장으로 옮기면 “이게 정말 맞나?”라는 빈틈이 드러남. 글쓰기는 자신의 이해도를 검증하고 더 조사하게 만드는 방법이 됨
게시하는 글마다 적어도 두 가지를 배우게 됨. 글을 쓰게 만든 최초의 발견과 집필하면서 새롭게 알게 된 사실이며, 쓰는 동안 아무것도 배우지 못했다면 게시할 만큼 흥미롭지 않은 글이라고 판단함
단순한 생각 모음보다 반론 가능한 하나의 주장을 세우고 이를 방어하는 글을 권함. 무엇이 가장 흥미로운 논점인지 찾아야 하고, 예상되는 비판에 답하려면 자연스럽게 더 조사하게 됨
잘 모르는 분야를 쓰는 것도 가치가 있음. 이제 막 배우는 사람은 전문가가 당연하게 넘길 수 있는 “애초에 어떤 문제를 해결하려는가”부터 설명할 수 있고, 조사하면서 기존 통념이 틀렸다는 사실을 발견할 수도 있음
제대로 쓰고 있는지는 집필 중 자신의 생각이 바뀌는지, 그리고 첫 초안의 결론이 서론보다 훨씬 명확해졌는지로 확인할 수 있음. 공개하지 않아도 글쓰기 자체로 효과가 있고 LLM에게 기술적 피드백을 받을 수도 있음
알고 있다고 생각하는 것을 스스로 써내려 나가며, 그 과정에서 몰랐던 점이나 내 주장의 빈약한 부분을 채워나가고, 때로는 결론에 이르러 의견을 바꿔버릴 수 있는 글쓰기의 힘.
특히, ‘초보자가 더 좋은 입문 설명을 만들 수 있다’는 점에 공감한다.
이제 배우기 시작한 사람은 기술적인 해법으로 바로 들어가기 전에 원래 해결하려는 문제가 무엇인지부터 설명할 수 있으며, 오히려 전문가가 아니기 때문에 독자와 같은 선상에서 기초부터 천천히 함께 걸어갈 수 있기 때문.
Ref https://news.hada.io/topic?id=32517
AI 에이전트에 작업을 반복 실행시키는 핵심은 자율성을 높이는 것보다 완료 조건과 제약을 명확히 정의하고, 어떤 판단은 사람이 계속 맡을지 결정하는 데 있다.
클로드 코드의 /goal과 /loop 활용하기
/goal: 측정 가능한 완료 조건까지 반복
/loop: 반복 실행과 외부 상태 확인
/loop 적용 후보가 될 수 있다중요한 것은, 작업을 위임하되 판단까지 위임하지는 않는 것.
Ref https://news.hada.io/topic?id=32519
AI가 잘하는 일
인간이 계속 맡아야 할 일
즉 AI는 대량의 변경에서 결함 후보를 빠르게 선별하는 역할, 인간은 맥락과 의도를 확인하고 수정 방향과 최종 판단을 조율하는 역할.
Ref https://news.hada.io/topic?id=32449&ref=surfit.io
/rewind) 제대로 쓰는 법: 체크포인트가 되살리는 것과 끝내 못 살리는 것Claude Code는 사용자가 프롬프트를 보낼 때마다 코드 상태를 자동으로 찍어 두고, /rewind 한 줄이면 그 시점으로 파일을 되돌린다. 다만 bash 명령으로 바뀐 파일, 서브에이전트가 고친 파일, 심볼릭 링크 경로는 되돌아오지 않는다.
/resume과 함께, 놓친 대화의 맥락이나 복원하고 싶은 코드의 체크포인트로 돌아가는 데 유용하게 사용할 수 있을 것 같다.
Ref https://wikidocs.net/blog/@openwiki/28229/?ref=surfit.io
우리 팀원이 작성한 글 ✌️ 내가 만드는 프로덕트가 테크블로그에 나오니 반갑다.
위 방법들을 활용하여 대용량 데이터를 클라이언트에 표로 그릴 때 성능을 고려하고, 잠재적인 버그들을 방지할 수 있었던 토스애즈 프론트엔드의 기술 고민 이야기.
Ref https://toss.tech/article/ads_dashboard_fe?ref=surfit.io
@inquirer/promptsCLI에서 대화형 프롬프트 작성을 가능하게 해주는 도구.
Ref https://www.npmjs.com/package/@inquirer/prompts
내가 너무 힘들어하는 여름이 공식적으로(?) 끝났다!
말도 많고 탈도 많았던 이번 여름. 그래도 역시 무사히 지나갔다.
한 가지 확고한 결심을 하니 오히려 마음이 홀가분해진 요즘
회사 일도, 개인의 일도 아쉬움 남지 않게 오롯이 집중해서 해내고 싶다.