본문 바로가기

카테고리 없음

TypeError: is not a function, 오류가 발생하는 이유와 해결 순서

TypeError: is not a function, 오류가 발생하는 이유와 해결 순서

자바스크립트 개발 중 TypeError: xxx is not a function이라는 오류를 만나면 분명 함수처럼 작성했는데 왜 실행되지 않는지 당황하기 쉽습니다.

라이브러리, 객체 메서드, import/export, 비동기 코드를 다루다 보면 비교적 자주 접하게 되는 오류인데요.
 
다행히 TypeError: is not a function 오류가 발생하는 이유는 비교적 명확합니다.
 
어떤 값을 함수처럼 호출했지만 실행 시점에 그 값이 실제 함수가 아니었다는 뜻입니다. 의미부터 주요 원인, 가장 빠르게 문제를 찾는 해결 순서까지 자세히 알아보겠습니다.
 
 

TypeError: is not a function이란?

자바스크립트에서는 함수 뒤에 괄호 ()를 붙여 호출합니다. 그런데 문자열이나 숫자, 일반 객체처럼 호출할 수 없는 값에 괄호를 붙이면 TypeError가 발생할 수 있습니다.

const value = "hello";
value();
// TypeError: value is not a function

 

여기서 중요한 부분은 value라는 이름 자체가 아니라 오류가 발생한 순간 value에 무엇이 들어 있었는지입니다. 따라서 함수 선언만 찾기보다 실제 런타임의 값과 타입을 확인하는 것이 해결의 핵심입니다.

 
 

is not a function 오류, 가장 흔한 원인 10가지

1. 함수 변수에 다른 값을 할당한 경우
원래 함수였던 변수에 문자열, 숫자, 객체 등을 다시 할당한 뒤 호출하면 오류가 발생합니다. 같은 변수명이 여러 위치에서 변경되고 있지 않은지 확인하세요.
 

2. 함수 이름을 잘못 입력한 경우
메서드명이나 함수명의 오타도 흔한 원인입니다. 자바스크립트는 대소문자를 구분하기 때문에 getDatagetdata 역시 서로 다른 이름입니다.

 
3. 객체에 존재하지 않는 메서드를 호출한 경우
객체에 해당 메서드가 있다고 생각했지만 실제로 정의되어 있지 않을 수 있습니다. 객체 구조와 프로토타입, 라이브러리 문서를 함께 확인하는 것이 좋습니다.

const person = {
  name: "지민"
};
person.getName();
// TypeError: person.getName is not a function

 
4. 같은 이름의 속성이 함수를 덮어쓴 경우
함수와 일반 속성에 동일한 이름을 사용하면서 예상과 다른 값이 남는 경우가 있습니다. 클래스나 객체를 구성할 때 메서드명과 데이터 속성명이 충돌하지 않는지 살펴보세요.
 
5. import/export 방식을 잘못 사용한 경우
ES Module에서는 default export와 named export의 가져오는 문법이 다릅니다. 내보낸 형태와 가져온 형태가 맞지 않으면 예상했던 함수를 제대로 얻지 못할 수 있으므로 모듈 정의부터 확인해야 합니다.
 

6. 함수 반환값을 다시 함수처럼 호출한 경우
어떤 함수가 문자열이나 객체를 반환하는데 그 결과에 다시 ()를 붙이면 문제가 생깁니다. 반환값의 타입을 확인하면 쉽게 발견할 수 있습니다.

 
7. 라이브러리 버전이나 API가 변경된 경우
패키지를 업데이트한 뒤 기존 메서드가 삭제되거나 사용법이 바뀌기도 합니다. 예전 예제 코드를 그대로 사용하고 있다면 현재 설치된 버전의 공식 문서를 확인해 보세요.
 
8. 비동기 처리 과정에서 예상과 다른 값을 받은 경우
Promise나 API 데이터를 처리하는 과정에서 함수가 들어올 것으로 예상했지만 실제 값은 다른 타입일 수 있습니다. 비동기 작업에서는 호출 직전 값을 확인하는 것이 중요합니다.
 

9. this 바인딩 문제로 잘못된 값을 참조하는 경우
객체 메서드를 다른 변수에 전달하거나 콜백으로 사용할 때 this가 예상과 달라질 수 있습니다. 이 경우 메서드 내부에서 참조한 값 때문에 연쇄적인 TypeError가 나타날 수 있어 호출 방식과 실행 컨텍스트를 함께 확인해야 합니다.

 
10. 플러그인이나 초기화 코드가 실행되지 않은 경우
외부 플러그인이 특정 메서드를 추가하는 구조라면 초기화 실패나 로딩 순서 때문에 예상한 함수가 준비되지 않을 수 있습니다. 스크립트 로드 여부와 초기화 순서를 점검해 보세요.
 
 

TypeError 해결 순서, 먼저 typeof부터 확인

오류를 빠르게 해결하려면 무작정 코드를 수정하기보다 순서대로 추적하는 것이 좋습니다.
 
첫 번째는 에러 메시지와 Stack Trace에서 문제가 발생한 파일과 줄 번호를 확인하는 것입니다.
 

두 번째로 해당 위치에서 호출하고 있는 값을 직접 출력합니다. typeof까지 함께 확인하면 함수인지 아닌지를 바로 판단할 수 있습니다.

console.log(myFunction);
console.log(typeof myFunction);
if (typeof myFunction === "function") {
  myFunction();
}

 

정상적인 함수라면 typeof 결과가 "function"으로 표시됩니다. 문자열이나 object, undefined 등이 나온다면 그 값이 어디에서 만들어지고 변경되었는지 거꾸로 추적하면 됩니다.

 
 

is not a function 해결, import와 객체부터 점검

타입 확인이 끝났다면 세 번째로 값의 출처를 찾아보세요. 객체에서 가져온 메서드라면 실제 객체를 출력하고, 모듈에서 가져온 함수라면 export/import 형태가 일치하는지 확인합니다.

// named export
export function getData() {
  return "data";
}
// named import
import { getData } from "./utils.js";
getData();

 
네 번째는 함수가 다른 값으로 덮어쓰이지 않았는지 확인하는 것입니다. IDE의 참조 검색 기능이나 디버거를 활용하면 해당 변수에 값이 할당되는 위치를 빠르게 찾을 수 있습니다.
 
마지막으로 라이브러리를 사용하는 코드라면 설치된 패키지 버전과 현재 공식 문서의 API를 비교하세요. 오래된 블로그 예제와 최신 버전의 사용법이 달라 오류가 발생하는 경우도 있기 때문입니다.
 
 

this 때문에 is not a function이 발생한다면?

this와 관련된 오류는 조금 더 세심하게 살펴봐야 합니다. 메서드를 객체에서 분리해 호출하면 호출 방식에 따라 원래 객체와의 연결이 달라질 수 있습니다.

const user = {
  name: "민수",
  getName() {
    return this.name;
  }
};
console.log(user.getName());

 

메서드 내부에서 this를 사용한다면 해당 함수가 어떤 방식으로 호출되는지를 함께 확인하세요. 필요에 따라 화살표 함수의 특성을 이해하거나 bind(), call(), apply() 등을 검토할 수 있습니다.

 
 

TypeError를 예방하는 실전 습관

이 오류를 예방하려면 함수나 메서드를 호출하기 전에 데이터 구조와 타입을 명확하게 관리하는 것이 중요합니다. 특히 외부 API나 라이브러리처럼 개발자가 완전히 통제하기 어려운 값은 실행 전에 검증하는 습관을 들이는 것이 좋습니다.
 
TypeScript를 활용하면 함수로 예상한 값에 다른 타입이 들어가는 실수를 개발 단계에서 발견하는 데 도움이 됩니다. ESLint, IDE 타입 추론, 테스트 코드까지 함께 활용하면 런타임에서 TypeError를 만날 가능성을 더욱 줄일 수 있습니다.
 

해결 순서확인할 내용
1단계에러 메시지와 발생 줄 확인
2단계호출하려는 값 console.log() 출력
3단계typeof로 실제 타입 확인
4단계값이 할당·변경되는 위치 추적
5단계객체의 메서드 존재 여부 확인
6단계import/export 형태 확인
7단계this와 호출 방식 확인
8단계라이브러리 버전과 공식 API 확인

 
TypeError: is not a function의 핵심은 간단합니다. 자바스크립트가 함수가 아닌 값을 함수처럼 실행하려 했다는 의미입니다. 에러가 발생하면 호출 대상의 실제 값과 타입부터 확인하고, 객체 메서드, 값 변경 과정, import/export, 라이브러리 버전과 호출 시점을 순서대로 추적해 보세요.
 
처음에는 복잡해 보이지만 “호출 직전 이 값은 정말 함수인가?”라는 질문에서 시작하면 대부분의 원인을 빠르게 좁힐 수 있습니다.
 
오늘 정리한 디버깅 순서를 기억해 두셨다가 비슷한 오류가 나타났을 때 활용해 보세요.