프로그래밍 지식/Javascript

Typescript 입문하기

raptarior 2026. 9. 7. 14:31

컴파일과 런타임에서의 타입스크립트

ts는 컴파일 단계에서 타입 체크가 이루어지고 js 파일을 생성하여 실행한다.
node ~~.ts 는 타입검사 없이 js 변환하여 실행된다 (타입검사가 이루어지지 않아 실행 속도는 빠르다)


순수 js 입장에서 ts의 타입은 타입 어노테이션(혹은 주석)에 불과한 참고사항일 뿐이어서 어겨도 에러가 발생하지 않는다.
따라서 코드가 실행되고 있는 시점은 js 런타임 환경이라 타입의 영향력이 없다.

여러 타입에 대해

  • Number와 number의 차이 (Boolean, String도 동일)
    Number는 js의 내장 객체
    number는 ts에서 쓰이는 타입

  • any 타입
let obj: any = { a: 1, b: 2 };
const n2: number = obj;
console.log(n2);
console.log(typeof n2);

// 출력값
// { a: 1, b: 2 }
// object


any는 타입 체크를 무시한다.

=> 일반적으로는 다른 타입을 대입할 때 에러가 발생하지만, any를 넣으면 타입이 무시하므로 주의하여 사용해야 한다.
(tsconfig에 noImplicitAny 항목으로 any를 금지할 수 있다)

 

  • 튜플

길이와 각 위치의 타입이 고정된 배열

type StringNumberPair = [string, number];
type Length2dOr3d = [number, number, number?]; // ? 항목은 선택적
type StringAndNumbers = [string, number[]]; // 두번쨰 이후 항목은 모두 number

 

null과 undefined

strictNullChecks : null과 undefined가 될 수 있는 값은 사용하기에 앞서 값을 테스트해야 한다.

function liveDangerously(x?: number | undefined) {
  console.log(x!.toFixed());
  console.log(x?.toFixed());
}


x!는 값이 null, undefined가 아님을 단언
x?는 x가 유효한 값일 경우만 직후의 코드 실행

x?의 타입은 number | undefined 이므로 사용 전에 좁히거나 기본값을 주는 것이 좋다

 

type

type n = number;

type ApiMeta = {
  requestId: string;
  timestamp: string;
};

type TicketResponse = ApiMeta & {
  ticket: Ticket;
};


기존 타입에 별칭을 부여하거나 복합적인 타입을 정의할 수 있으며, & 를 활용하여 조합도 가능하다

type A2 = {
  x: string;
};

type B2 = A2 & {
  x: number; // 이미 x: string인 상태에서 추가
};


이름이 겹치는 경우 x: string & number로 불가능한 타입(never)가 되어 발견하기 어려운 에러를 발생시킨다.
interface는 이 경우 컴파일 에러를 발생시켜 더 안전하다.

 

union

가능한 타입 혹은 값의 후보를 표현한다.

type ID = number | string;
type UserStatus = 'ONLINE' | 'OFFLINE' | 'WITHDRAWN';
type Size = number | 'auto';

 

 

enum과 달리 런타임에는 사라지며, 리터럴 값 자체를 사용한다.

interface

관례적으로 객체나 DTO 형태는 interface, 그 외엔 type을 사용한다.

interface User { 
  id: string; 
  name: string; 
}

 

타입과 비슷하게 활용할 수 있으며 & 대신 extends로 확장한다.
같은 인터페이스 이름을 여러 번 선언하면 자동으로 내용이 합쳐진다.
유니온 타입, 튜플 등은 적용할 수 없으며, 이 경우 type을 사용해야 한다.

  • 인덱스 시그니처
interface Dictionary {
  [key: string]: number;
}


프로퍼티의 타입을 한정할 수 있다.

  • 호출 시그니처
interface FunctionInterface {
  (num: number): number;
}

const func: FunctionInterface = (num) => num * 2;


(매개변수): 반환타입 의 형태로 함수의 호출 타입 인터페이스를 정의한다.

  • 오버로드 시그니처
interface myInterface {
    (arg: string): string;
    (arg: number): number;
}

const myFunction: OvInterface = (arg: any) => arg;
console.log(myFunction('Hello'));
console.log(myFunction(42));


같은 함수 인터페이스에 대해 여러 호출 방식을 가진다.

제네릭

타입을 담는 변수. any 타입 대신 안전하게 사용할 수 있다.

interface GenericInterface {
  <Type>(arg: Type): Type;
}

interface GenericInterface<Type> {
  (arg: Type): Type;
}


제네릭을 인터페이스 레벨로 올릴 경우 사용할 때 타입을 확정해야 한다.
함수 시그니처에만 두면 호출할 때마다 다른 타입으로 쓸 수 있다.

interface hasLength {
  length: number;
}

function fn<Type extends hasLength>(arg: Type): Type {
  return arg.length;
}


제네릭에 extends로 제약을 걸어 타입 중에서도 조건을 만족하는 경우만으로 좁힐 수 있다.

function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
  return obj[key];
}

let x = { a:1, b:2, c:3 };
getProperty(x, "a");


keyof Type은 'Type의 모든 key 이름 union' 을 만든다. (Key = 'a' | 'b' | 'c'; 이런 식으로)

  • 제네릭에 클래스 타입 사용하기
function create<Type>(c: { new (): Type }): Type {
  return new c();
}


클래스 인스턴스를 만드는 팩토리 함수 형태이다.
c에 클래스 자체가 들어가며 new c()로 새로운 c 클래스의 인스턴스를 반환한다.

ts의 값 좁히기 (narrowing)

타입스크립트는 조건문을 통해 가능한 타입 후보를 좁혀가거나 특정 타입임을 추론할 수 있다
값을 안전하게 좁히려면 typeof 를 활용 (타입 가드)

주의할 점
"", NaN, 0 => false
[], {} => true
typeof null === 'object'

strs && typeof strs === 'object'와 같은 방법으로 null을 방어할 수 있다

 

  • narrowing의 활용
// Bad Code
interface Shape {
  kind: "circle" | "square";
  radius?: number;
  sideLength?: number;
}

// Good Code
interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

type Shape = Circle | Square;


위 쪽의 코드는 radius와 sideLength가 null로 존재할 가능성이 있다.
밑의 코드처럼 설계하여 switch case 구문을 활용하면 안전하게 타입을 확정지어 사용할 수 있다.

 

 

참고 공식 문서

'프로그래밍 지식 > Javascript' 카테고리의 다른 글

React 배우기 4. 이벤트 핸들링  (0) 2025.04.15
React 배우기 3. Hooks와 Lifecycle  (0) 2025.03.28
React 배우기 2. 컴포넌트  (0) 2025.03.24
React 배우기 1. JSX  (0) 2025.03.21
배우기 *. 실습  (0) 2025.03.13