iBetter Books
수정

빨간 줄이 뜨는 건 좋은 신호입니다

TypeScript를 처음 배울 때 가장 당황스러운 순간은 아마 코드 아래에 빨간 물결선이 쫙 깔릴 때일 겁니다. "내가 뭘 잘못한 거지?" 싶어서 무조건 any를 붙이거나 @ts-ignore를 달고 싶어집니다.

그런데 빨간 줄은 나쁜 신호가 아닙니다. TypeScript가 "여기 문제가 있는 것 같아요"라고 미리 알려주는 것입니다. 이 메시지를 읽을 줄 알면, 에러는 적이 아니라 조수가 됩니다.

에러 메시지는 대부분 같은 패턴을 가지고 있습니다. 자주 만나는 다섯 가지를 살펴보겠습니다.

에러 1. Type 'X' is not assignable to type 'Y'

타입 불일치 에러입니다. TypeScript를 배우는 동안 가장 자주 만납니다.

let age: number = 25;age = "스물다섯";// 에러: Type 'string' is not assignable to type 'number'.

메시지를 읽으면 바로 알 수 있습니다. "stringnumber에 할당할 수 없다"는 뜻입니다. age는 숫자인데 문자열을 넣으려 했으니 당연합니다.

해결 방법은 간단합니다. 타입에 맞는 값을 넣거나, 타입 선언을 바꾸면 됩니다.

let age: number = 25;age = 26;                  // OK — 숫자 넣기let ageText: string = "스물다섯"; // 처음부터 string으로 선언

함수 반환값에서도 이 에러가 납니다.

function getScore(): number {  return "100점"; // 에러: Type 'string' is not assignable to type 'number'.}

반환 타입이 number인데 string을 반환하려 했습니다. 숫자 100을 반환하거나, 반환 타입을 string으로 바꾸면 됩니다.

에러 2. Property 'X' does not exist on type 'Y'

존재하지 않는 속성에 접근하려 할 때 납니다.

const user = { name: "김민수", age: 25 };console.log(user.email);// 에러: Property 'email' does not exist on type '{ name: string; age: number; }'.

user 객체에는 nameage만 있고 email은 없습니다. TypeScript는 객체의 형태를 알고 있으므로 없는 속성 접근을 막습니다.

해결 방법은 오타인지 확인하거나, 필요하다면 속성을 추가하는 것입니다.

const user = { name: "김민수", age: 25, email: "[email protected]" };console.log(user.email); // OK

배열 메서드에서도 이 에러를 만납니다.

const numbers = [1, 2, 3];numbers.contains(1);// 에러: Property 'contains' does not exist on type 'number[]'.

JavaScript 배열에는 contains가 없고 includes가 있습니다. 메서드 이름을 잘못 기억한 경우입니다. VS Code에서 .을 찍으면 자동완성 목록이 뜨므로 활용하면 좋습니다.

에러 3. Argument of type 'X' is not assignable to parameter of type 'Y'

함수에 잘못된 타입의 인수를 전달할 때 납니다.

function greet(name: string) {  return `안녕하세요, ${name}!`;}greet(42);// 에러: Argument of type 'number' is not assignable to parameter of type 'string'.

에러 1과 비슷하게 생겼지만, "할당"이 아니라 "인수(argument)"와 "매개변수(parameter)"라는 단어가 나옵니다. 함수 호출 시의 타입 불일치입니다.

해결 방법은 올바른 타입의 값을 전달하거나, 함수 매개변수 타입을 바꾸는 것입니다.

greet("김민수"); // OK// 또는function greet(name: string | number) {  return `안녕하세요, ${String(name)}!`;}

에러 4. Object is possibly 'undefined'

값이 undefined일 수 있는 상황에서 바로 사용하려 할 때 납니다.

const users = ["김민수", "이영희", "박철수"];const found = users.find((u) => u === "최지영");console.log(found.toUpperCase());// 에러: Object is possibly 'undefined'.

Array.find()는 찾는 값이 없으면 undefined를 반환합니다. TypeScript는 found의 타입이 string | undefined임을 압니다. undefined일 수 있는 값에 .toUpperCase()를 바로 호출하면 런타임 에러가 날 수 있으므로 막는 것입니다.

해결 방법은 먼저 값이 있는지 확인하는 것입니다.

const found = users.find((u) => u === "최지영");// 방법 1: if로 확인if (found !== undefined) {  console.log(found.toUpperCase()); // OK}// 방법 2: 옵셔널 체이닝console.log(found?.toUpperCase()); // 없으면 undefined 반환// 방법 3: 기본값 제공const name = found ?? "알 수 없음";console.log(name.toUpperCase()); // OK

이 에러는 사실 좋은 에러입니다. 미리 확인하지 않으면 런타임에서 "Cannot read properties of undefined" 에러를 만나게 됩니다.

에러 5. Cannot find name 'X'

선언되지 않은 이름을 사용하려 할 때 납니다.

console.log(username);// 에러: Cannot find name 'username'.

username이라는 변수가 선언된 적 없습니다. 오타이거나, 아직 선언하지 않은 경우입니다.

const usrname = "김민수";console.log(username); // 오타! usrname을 username으로 잘못 씀

또는 다른 파일에서 가져와야 하는데 import를 빠트린 경우입니다.

// Router를 사용하려는데 import를 안 함const router = new Router(); // 에러: Cannot find name 'Router'.// import 추가 후import { Router } from "express";const router = new Router(); // OK

VS Code에서는 이 에러가 날 때 전구 아이콘(자동 수정 제안)이 뜨기도 합니다. 클릭하면 자동으로 import를 추가해줍니다.

에러 메시지 읽는 요령

에러 메시지는 보통 이런 구조로 되어 있습니다.

[에러 유형]: [무엇이] [어떤 타입에] [어떤 조건을] 만족하지 않는다.

긴 에러 메시지가 나와도 당황하지 말고 키워드를 찾아보세요.

  • is not assignable to — 타입 불일치
  • does not exist on type — 존재하지 않는 속성이나 메서드
  • possibly 'null' 또는 possibly 'undefined' — null/undefined 가능성
  • Cannot find name — 선언되지 않은 이름
  • is not a function — 함수가 아닌 것을 함수처럼 호출

에러 메시지에 있는 타입 이름을 확인하면 "무엇이 문제인지"를 파악할 수 있습니다. 에러 위치(파일명, 줄 번호)도 함께 표시되므로 그 줄을 먼저 확인하세요.

에러 정리

에러 메시지 원인 해결 방법
Type 'X' is not assignable to type 'Y' 타입 불일치 타입에 맞는 값 사용
Property 'X' does not exist on type 'Y' 없는 속성/메서드 오타 확인, 속성 추가
Argument of type 'X' is not assignable to parameter of type 'Y' 함수 인수 타입 불일치 올바른 타입으로 전달
Object is possibly 'undefined' undefined 가능성 if 확인 또는 옵셔널 체이닝 사용
Cannot find name 'X' 선언 없는 이름 선언 추가 또는 import 확인

PART 02에서는 TypeScript의 기본 타입들을 탐험했습니다. 변수에 이름표를 붙이는 것에서 시작해, TypeScript의 추론 능력, 배열과 튜플, 선택지를 제한하는 리터럴 타입과 열거형, 그리고 특수한 세 타입 any, unknown, never까지 살펴봤습니다.

다음 PART에서는 여러 속성을 묶어서 표현하는 방법인 객체 타입과 인터페이스를 본격적으로 다루겠습니다. 타입으로 생각하는 습관이 시작됩니다.