Today I Learn

[TS] Typescript Type Alias

diligentCat 2025. 1. 4. 17:41

💡타입 별칭(Type Alias)의 개념

Typescript에서 Type Alias는 타입(기본형, 인터페이스 등)에 별명을 붙여 재사용가능한 문법을 제공한다. 이를 통해 복잡한 타입을 간단한 이름으로 표현할 수 있으며, 코드의 가독성을 높이고 유지보수가 용이해진다.
➡️ interface / class 표현과 표환되나 객체 중심의 설계에서는 interface / class 를 활용하고, 타입의 단순화에서는 type alias 를 활용한다.
type ID = number | string;
type PASSWORD = string;

let userId1: ID; // 별칭 사용 재활용 가능.
let userId2: number | string; // 하드 코딩

userId1 = "test1";
userId2 = "test2";
userId1 = "100";
// userId1 = false; Boolean은 사용 불가

let password: PASSWORD = "12345";

 

💡기본 타입의 type alias 활용

기본 타입의 type alias는 alias 문법만 사용 가능하며, interface로는 표현이 불가능하다.
 union 패턴: 기본형 union과 사용자 리터럴을 결합하여 다양한 type을 결합한 type 생성 가능
nullable 패턴: 유니온 타입의 null을 포함하면 null을 허용하게 끔 설계할 수 있다.
type UserID = number | string;
type Password = string;
type UserName = string | null;
type Authority = "USER" | "ADMIN" | null;
type UnionType = UserID | UserName;

let id1: UserID = "test1";
let name1: UserName = "Hong"
let name2: UserName = null;
let authority1: Authority = "USER"
let authority2: Authority = null;

function makeUser(id: UserID, password: Password, name: UserName, authority: Authority): void {
    console.log(id, password, name, authority);
}

makeUser("test", "1234", "Hong", "USER");

 

💡함수 파라미터, 반환 값의 type alias 활용

함수의 파라미터 혹은 반환 값에도 type alias를 적용 가능하다.
type Param1 = string | number;
type Param2 = boolean | null;
type Status = "success" | "error" | "loading";

function func1(param1: Param1, param2: Param2, status: Status): Status {
    console.log(param1, param2, status);
    return status;
} 

func1("test", true, "success");
func1(12345, null, "error");
let result = func1("test", false, "loading");

 

💡함수의 type alias 활용

함수의 인자와 리턴 타입에 대한 type alias를 정의하여 함수의 형태를 지정할 수 있다.
이렇게 지정된 함수 type alias는 함수 구조의 상속이나 callback 구조의 제한으로도 활용 할 수 있다.
type clac = {
    (a: number, b: number): number;
}

type clac2 = {
    // 매개 변수,           리턴값
    (a: number, b: number): number;
}

const add: clac = (x, y) => x + y;
const minus: clac = (x, y) => x - y;
const multi: clac = (x, y) => x * y;
const divide: clac = (x, y) => x / y;
// const error:clac = (x, y, z) => x + y + z;

function print(callback: clac, a: number, b: number){
    console.log(callback(a, b));
}

print(add, 5, 8);
print((a, b) => a % b, 17, 5); // 2

💡객체의 type alias 활용

type alias를 통해 객체의 별칭을 정할 수 있다. 이때 type을 정의하는 문법은 interface와 완벽히 호환된다. 또한 상속과 같은 메커니즘도 활용 가능 한대, type alias의 상속은 & (Intersection) 연산을 활용한다.
// interface User
interface User1 {
    name: string;
    age: number;
    mailing?: boolean;
    hobby?: string[];
}

// type을 통한 User 설계 완벽호환 가능
// interface와 달리 IDE에서 안 쪽 내용을 더 잘 보여준다.
type User2 = {
    name: string;
    age: number;
    mailing?: boolean;
    hobby?: string[];
}

let user1: User1 = {name: "hong", age: 20, mailing: false, hobby:["잠자기"]};
let user2: User2 = {name: "hong", age: 20, mailing: false};
type Parent1 = {
    name: string;
    age: number;
};

type Parent2 = {
    address: string;
    mailing?: boolean;
}

// 상속하는 방법1
type Child1 = Parent1 & Parent2;

// 상속하는 방법2 
type Child2 = Parent1 & {
    address: string;
    mailing?: boolean;
} // & Parent1 <- 여기에 작성해도 상관없음. 

const parent1: Parent1 = {
    name: "Hong",
    age: 31,
}

const child1: Child1 = {
    name: "Hong",
    age: 32,
    address: "서울시 강남구",
    mailing: true,
}

const child2: Child2 = {...parent1, address: "서울시 강남구", mailing: false};
const child3: Child2 = {...child1, address: "서울시 중구"};

💡중첩 객체의 type alias 활용

중첩 객체에 type alias를 사용하여 객체 내부의 또 다른 객체를 적용할 수 있다.
// 중첩 객체의 type alias 사용 (interface로도 가능)

type Address = {
    street: string;
    city: string;
}

type Person = {
    name: string;
    age: number;
    address: Address; 
    // 기존에 만들어둔 type을 사용 가능
}

const person: Person = {
    name: "Hong",
    age: 19,
    address: {
        street: "남부순환로",
        city: "Seoul"
    }
}

💡Type alias vs Interface

Type alias는 interface 대비 더 많은 타입의 별칭을 정할 수 있거나 문법으로 더 유연한 문법을 제공한다. 하지만 객체의 표현에 있어서 조금 더 표준적인 문법은 interface 사용을 권장하고 있다.
특징 Type alias Interface
기본 사용 목적 모든 타입 정의 가능 객체 타입 정의에 주로 사용
타입 확장 &(Intersection) 사용 extends 키워드로 확장 가능
타입 병합 (Merging) 불가능 가능
키 제한  가능 (keyof, Mapped Types 등과 호환) 가능 (keyof, Mapped Types 등과 호환)
함수 타입 정의 간단하게 정의 가능(type f = (a:number) => viod) 함수 타입 정의는 call signature 사용 가능
유니언 타입 정의가능(type Status = "success" | "error") 불가능
튜플 타입 정의 가능(type Point = [number, number] 불가능
유연성 다양한 타입 정의 가능 객체 타입 정의에 특화
사용 사례 복잡한 타입 정의, 유니언 타입, 튜플, 함수 객체와 클래스 설계 시 사용
컴파일러 오류메시지 상대적으로 간결하지 않을 수 있음 직관적인 오류 메시지 제공