TypeScript 타입 종류 및 타입 정의 방법

TypeScript 타입 종류 및 문법 정리

기본 원시 타입 (Primitive Types)

// 문자열만 저장 허용
let 변수명: string = "문자";

// 숫자만 저장 허용 (정수, 실수 모두 포함)
let 변수명: number = 숫자;

// 아주 큰 정수 저장 허용
let 변수명: bigint = 123456789012345678901234567890n;

// 참/거짓만 저장 허용
let 변수명: boolean = true;

// null 값만 저장 허용
let 변수명: null = null;

// undefined 값만 저장 허용 (값이 할당되지 않음)
let 변수명: undefined = undefined;

// 고유한 식별자만 저장 허용
let 변수명: symbol = Symbol("id"); // 고유한 식별자 생성 함수 (객체 키로 사용 가능)

원시 타입 변수는 객체 참조가 아닌, 단일 프리미티브 값 자체를 저장합니다.
‘: 타입명’ 처럼 타입 주석 (타입 어노테이션) 형태로 변수 타입을 정의할 수 있습니다.

리터럴 타입

let 변수명: 값 = 값;

리터럴 타입은 특정 프리미티브 타입 값 하나만 허용하는 타입입니다.

배열 타입 (Array)

// 타입 어노테이션 문법으로 배열 타입 정의
let 변수명: number[] = [1, 2, 3];
let 변수명: string[] = ["문자1", "문자2"];

// 제네릭 문법으로 배열 타입 정의
let 변수명: Array<boolean> = [true, false];

// 유니온 타입 배열 정의 (다양한 타입 값 저장 배열)
let 변수명: (string | number)[] = ["문자", 30, 40];

배열은 주로 동일한 타입 값들의 집합입니다.
다양한 타입 값을 저장할 수 있는 유니온 타입 배열도 정의 가능합니다.

다차원 배열 정의 방법

let 변수명: number[][] = [
  [1, 2, 3],
  [4, 5]
]

number 타입 변수를 담는 2차원 배열 예시입니다.

배열 값 추가 및 제거 방법

// 배열 값 추가
배열명.push(값);

// 배열 값 삭제
배열명.pop();

위와 같이 배열 값을 추가하거나 삭제할 수 있습니다.

튜플 타입

let 변수명: [string, number] = ["나이", 30];

튜플은 다른 타입을 함께 저장할 수 있고, 길이와 타입이 고정된 배열입니다.
튜플도 배열이므로, push/pop 함수 사용 가능하지만 타입 체크가 안될 수 있어 주의가 필요합니다.

튜플 요소를 갖는 배열 정의 방법

const 변수명: [string, number][] = [
  ["홍길동", 1],
  ["김지후", 2],
  ["한빛나", 3]
]

string, number 타입 순서의 튜플을 담는 2차원 배열 예시입니다.

객체 타입 (Object)

// 객체 리터럴 타입 정의
let 변수명: {
  id?: number; // ? : 옵셔널 프로퍼티 (있어도 되고, 없어도 됨)
  name: string; // 필수 프로퍼티
  readonly pw: string; // 읽기 전용 프로퍼티 (값 수정 불가)
} = {
  id: 1,
  name: "오시후",
  pw: '!@#asj'
}

// 객체 속성 접근 가능
변수명.id;

프로퍼티명, 프로퍼티 타입이 정해진 객체입니다.

타입 별칭으로 객체 타입 정의

// 타입 별칭 정의
type 타입별칭명 = {
  id: number;
  name: string;
  pw: string;
}

// 타입 별칭으로 객체 타입 정의
let 변수명1: 타입별칭명 = {
  id: 1,
  name: "오시후",
  pw: '!@#asj'
}
let 변수명2: 타입별칭명 = {
  id: 2,
  name: "한지연",
  pw: 'fgh%$2!'
}

타입 별칭 정의 후, 동일한 객체 타입을 여러 객체에 재사용할 수 있습니다.
중복된 타입 정의 로직을 줄일 수 있다는 장점이 있습니다.

인덱스 시그니처로 객체 타입 정의

type 타입별칭명 = {
  [key: string]: string;
  키1: string // 고정 프로퍼티 작성 가능 (변수 선언 시 키1 값이 필수인 경우)
}

let 변수명: 타입별칭명 = {
  키1: "값",
  키2: "값",
  키3: "값"
}

키, 값 타입이 모두 동일하게 들어오는 경우 인덱스 시그니처를 활용하면 좋습니다.

Enum 타입

// 열거형 타입 정의
enum Role {
  ADMIN = 0,
  USER = 1,
  GUEST // 숫자 생략 시 자동 숫자 할당 (+1)
}

// 객체 값으로 열거형 타입 사용
const 변수명 = {
  name: "김정호",
  role: Role.ADMIN
}

열거형으로 값 집합을 정의합니다.
enum 타입은 컴파일 시 양방향 매핑이 된 JavaScript 객체로 변환됩니다.

any 타입

// 모든 타입 허용하는 any 타입 변수 정의
let 변수명:any = 10;

// 모든 타입 값 저장 가능
변수명 = "10";
변수명 = () => {};

// 다른 타입 변수에 any 타입 변수 저장 가능
// 컴파일 시 정상, 런타임 에러 발생 가능
let num: number = 12;
num = 변수명;

모든 타입 값을 허용해서, 특정 변수 타입을 모를 때 사용할 수 있는 타입입니다.
타입 검사를 하지 않으므로 런타임 에러가 발생할 수 있어 사용이 지양되는 타입입니다.

unknown 타입

// 모든 타입 허용하는 unknown 타입 변수 정의
let 변수명: unknown = 값;

// 모든 타입 값 저장 가능
변수명 = "";
변수명 = 1;
변수명 = () => {};

// 다른 타입 변수에 unknown 타입 변수 저장 불가
let num: number = 12;
num = 변수명;

// 타입 정제 시, 다른 타입 변수에 unknown 타입 변수 저장 가능
if (typeof 변수명 === "number") {
  num = 변수명;
}

모든 타입 값을 허용하지만, 다른 타입에 할당 시 타입 검사가 진행되는 타입입니다.
특정 변수 타입을 모를 때 any 타입보다 unknown 타입 사용이 더 권장됩니다.

void 타입

// 함수 반환 값 없음 명시
function 함수명(): void {
  console.log("로그 출력");
}

// 변수 값 없음 명시
let 변수명: void;

변수명 = 1; // 변수 값 지정 불가
변수명 = undefined; // 변수 값 undefined 저장 가능

void 타입은 아무것도 없음을 의미하는 타입입니다.
주로 void 변수보다는 반환값이 없는 함수로 사용됩니다.

never 타입

// 함수 반환 값 존재할 수 없음 명시
function 함수명(): never {
  while (true) {}
}

// 변수 값 존재할 수 없음 명시
let 변수명: never;

// 모든 변수 값 할당 불가 (전부 에러 발생)
변수명 = 1;
변수명 = {};
변수명 = undefined;
변수명 = null;

반환 값을 절대 반환하지 않는 함수, 예외 발생 함수 등에 사용하는 타입입니다.

함수 타입

// 한수 매개변수 타입 지정
function 함수명(매개변수명1: string, 매개변수명2: number) {
  
}

// 함수 반환 값 타입 지정
function 함수명(): string {
  return "값";
}

함수의 매개변수 타입, 반환값 타입 지정이 가능합니다.

Union 타입

let 변수명: (string | number) = 값;

여러 타입 중 하나를 지정 가능한 타입입니다.

인터섹션 타입

type Admin = { role: "admin" };
type User = { name: string };

type AdminUser = Admin & User;

const person: AdminUser = {
  role: "admin",
  name: "지후"
};

여러 타입을 동시에 만족해야 하는 타입입니다.