TypeScript의 승리. 그 결과 우리가 실제로 얻은 것은 무엇인가.

이제 더 이상 TypeScript 사용 여부를 두고 논쟁하지 않습니다. 새로운 프로젝트는 기본적으로 TypeScript를 사용합니다. 논쟁은 끝났습니다.

진정한 가치는 단순히 오타를 잡아내는 데 있지 않습니다. 그 이상의 의미가 있습니다.

함수 시그니처는 문서 역할을 합니다. 결코 낡은 정보가 되지 않습니다. 코드가 변경되면 컴파일러가 빌드 실패를 알립니다.

이 함수를 보세요:

function scheduleReminder(
  userId: string,
  at: Date,
  channel: "email" | "push" | "sms",
): Promise<ReminderId>;

이 함수를 어떻게 호출해야 하는지 정확히 알 수 있습니다. 무엇이 필요하고 무엇을 반환하는지 알 수 있습니다. channel이 세 가지 특정 문자열 중 하나여야 한다는 사실도 알 수 있습니다.

나중에 "slack" 옵션을 추가하면, 컴파일러가 코드의 모든 부분을 업데이트하도록 강제합니다. 주석은 시간이 지나면 낡아서 잘못된 정보를 남기게 됩니다.

타입이 없는 코드에서는 필드 이름을 바꾸는 것이 두렵게 느껴집니다. 문자열을 검색하며 운에 맡겨야 하죠. 하지만 TypeScript에서는 타입을 변경하기만 하면 됩니다. 컴파일러가 깨진 모든 부분에 대한 할 일 목록을 제공합니다. 리팩터링이 안전해집니다.

타입은 AI 활용에도 도움이 됩니다.

AI 모델은 JavaScript에서 코드의 형태를 추측합니다. 반면 TypeScript에서 타입은 곧 명세(specification)입니다. AI는 무엇이 허용되는지 알 수 있습니다. 실수는 프로덕션 환경의 크래시가 아닌 에러로 나타납니다.

타입은 가드레일 역할을 합니다. 모든 줄을 일일이 손으로 확인할 필요 없이, AI가 생성한 코드를 확신을 가지고 사용할 수 있게 해줍니다.

다음 규칙을 통해 더 나은 타입을 작성하세요:

• 많은 불리언(boolean) 대신 유니온(union)을 사용하세요. "loading" | "error" | "ready"와 같은 상태 값은 세 개의 개별 플래그보다 훨씬 낫습니다. • 도메인 타입을 명명하세요. 의도를 명확히 하기 위해 type Cents = number와 같이 사용하세요. • any를 피하세요. 대신 unknown을 사용하고 타입을 좁혀(narrowing) 나가세요. • 타입 추론(inference)을 활용하세요. 함수 시그니처와 같은 경계 부분에는 타입을 명시하되, 나머지는 자연스럽게 흐르도록 두세요.

TypeScript는 코드베이스를 강제된 계약(contract)의 집합으로 바꾸어 놓았습니다. 이러한 계약 덕분에 두려움 없는 리팩터링과 신뢰할 수 있는 AI 지원이 가능해집니다.

우리는 버그를 막기 위해 타입을 사용하기 시작했습니다. 하지만 이제는 다른 모든 것의 토대가 되기 때문에 타입을 계속 사용합니다.

Source: https://dev.to/parsajiravand/typescript-won-heres-what-that-actually-bought-us-53lo