far

[Typescript] File은 단순히 타입이 아니다. 본문

Typescript

[Typescript] File은 단순히 타입이 아니다.

Eater 2025. 3. 19. 21:55

Next.js에서 string인 경우와 File인 경우를 나눠야 해서 instanceof File이라고 작성을 했더니 잘 돌아가길래 이게 왜 런타임 환경에서 돌아가는걸까? 라는 생각이 들어 알아봤다.

1. TypeScript는 컴파일 시점에만 존재한다

일반적으로 interface나 type등 타입스크립트는 컴파일 시점에만 타입 정보를 활용하고, 컴파일 후 전부 사라지고 자바스크립트 코드만 남는다.

// 컴파일 전
interface User {
  id: number;
  name: string;
}

function getUser(user: User): void {
  console.log(user.name);
}

// 컴파일 후
"use strict";
function getUser(user) {
    console.log(user.name);
}

즉, 타입스크립트에서 정의한 타입 정보는 런타임에 남아있지 않기 때문에 instanceof User는 사용할 수 없는 코드가 된다.

2. 하지만 instanceof File은 왜 런타임에서 동작했지?

나는 File 타입을 여태까지 그냥 타입으로만 사용하고 있어서 인터페이스인줄 알고 있었다. 하지만 File은 브라우저 런타임 환경에서 실제로 존재하는 전역 클래스라고 한다. Typescript의 lib.dom.d.ts(브라우저 관련 타입 정의)를 보면 아래와 같이 되어있다.

interface File extends Blob {
    readonly lastModified: number;
    readonly name: string;
    // ...
}

declare var File: {
    prototype: File;
    new(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): File;
};

declare에서 JS환경에 File이라는 전역 변수가 있으며 생성자 함수라는 것을 Typescript에게 알려주고 있으며, 브라우저 콘솔창에서 File을 찍어보면 함수 형태로 된 진짜 생성자가 있다. (f File() { ... } 이렇게 되어있는)

이 말은 자바스크립트 런타임 환경에서 typeof File === 'function'가 되므로 instanceof도 정상적으로 동작하게 되는 것이다.

 

또한, File과 같이 Javascript표준 API나 브라우저/Node 환경에서 제공하는 빌트인 객체인 Blob, Date, Error 등등 역시 Typescript에 File과 같은 생성자가 존재하며, 실체가 런타임에 있는 전역 클래스이다.

3. 만약 런타임 환경에서도 타입 검증이 필요하다면?

이 파트는 그냥 타입가드를 사용하면 되는거 아닌가? 싶긴 한데, class로 검증하는 방법이 있다.

class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}

function tmp(obj: any) {
  if (obj instanceof Person) {
    console.log(obj.name);
  } else {
    console.log("Person이 아님");
  }
}

이렇게 class로 작성하면 Javascript코드에 실제로 남기 때문에 instanceof Person을 사용할 수 있게 된다.

하지만 아직은 클래스를 사용해서까지 타입 검증을 해야하는 구현을 해본적이 없어서 사용할 일이 있을지는 잘 모르겠다.

'Typescript' 카테고리의 다른 글

[Typescript] Never에 대해서  (0) 2023.03.17
[Typescript] Type과 Interface의 차이점  (0) 2023.03.12
useRef에 타입 주기  (0) 2022.12.12
Comments