WEB/TypeScript

[TypeScript] 타입 별칭, 함수(this, overloading)

devOhzl 2024. 8. 13. 19:38

타입 별칭 (Alias)

type 키워드를 사용하여 타입에 별도 이름(별명) 을 부여한다. 

할당 연산자를 붙여줘야한다.

 

type TypeA = string

단일 타입에 별칭을 부여하는 것은 크게 유용하지 않다.

 

type TypeB = string | number | boolean

타입 별칭은 단일 타입보다는 union( | )이나 ampersan0d( &) 기호를 사용하는 intersection 타입에서 별칭을 부여하여 재사용하는데 사용하는게 좋다.

 

type TypeA = string
type TypeB = string | number | boolean

type User = {
  name: string
  age: number
  isValid: boolean
} | [string, number, boolean]

const userA: User = {
  name: 'ohzl',
  age: 27,
  isValid: true
}
const userB: User = ['msns', 30, false]

function someFunc(param: TypeB) : TypeA {
  switch (typeof param){
    case 'string': 
      return param.toUpperCase()
    case 'number':
      return param.toFixed(2)
    default:
      return true    // error: string 타입을 반환해야한다.
  }
}

 

객체 데이터의 type을 지정할 때 인터페이스 ? 타입 별칭 ? 어떤 것을 사용해야할까

type TypeUser = {
  name: string
  age: number
  isValid: boolean
}

interface InterfaceUser {
  name: string
  age: number
  isValid: boolean
}

const userA: TypeUser = {
  name: 'ohzl',
  age: 27,
  isValid: true
}

const userA: InterfaceUser = {
  name: 'ohzl',
  age: 27,
  isValid: true
}

문법의 차이점은 타입 지정을 할 때는 할당연산자를 사용해야 한다는 것이다.

기능적으로는 큰 차이가 없고 취향에 맞게 사용할 수 있다.

굳이 권장을 하자면 인터페이스 방식을 권장한다.

 

단지 type 별칭은 객체 데이터의 타입을 만드는 구조라기 보다는 다양한 타입의 별칭을 지정하는 용도라서 사용 범위가 넓은데

인터페이스는  함수나 배열도 지정할 수 있지만 기본적으로는 객체 데이터를 전제하므로 굳이 추천하자면 인터페이스를 추천한다.

 

그렇다면 인터페이스와 타입별칭의 차이점도 알아보자

1. 확장 가능성

타입 별칭은 새 속성을 추가하기 위해 다시 열 수 없지만, 인터페이스는 항상 확장 가능하다.

interface Animal {
  name: string;
}
interface Bear extends Animal {
  honey: boolean;
}
const bear = getBear();
bear.name;
bear.honey;

인터페이스는 ‘extends’라는 키워드로 자신에게 주어진 메서드와 변수 정의의 범위 자체를 늘려나간다.

 

type Animal = {
  name: string;
};
type Bear = Animal & {
  honey: Boolean;
};
const bear = getBear();
bear.name;
bear.honey;

 타입 별칭은 집합 연산의 개념으로 (‘&’, ‘|’) 교집합, 합집합의 개념으로 자신의 범위를 늘려간다.

 

2. 이름 중복 사용

인터페이스는 이름을 중복으로 선언하면 내용을 합친다 (선언 병합)

타입 별칭은 이름을 중복으로 사용할 수 없다.

 

3. 사용할 수 있는 타입의 차이

인터페이스는 주로 객체 타입을 정의한다.

타입 별칭은 중복된 타입 코드를 줄이고 주요 데이터 타입 / 인터섹션 타입 / 유니언 타입 등을 정의하는데 사용한다.

type PartialPointX = { x: number };
type PartialPointY = { y: number };

// intersection
type IntersectionPoint = PartialPointX & PartialPointY;

// union
type UnionPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];

 

함수 - 명시적 this

interface Cat {
  name: string
  age: number
}

const cat : Cat = {
  name: 'ohzl',
  age: 27
}

function hello(message: string){
  console.log(`Hello ${this.name}, ${message}`)
}

hello.call(cat, 'Your are pretty awesome!')

 

hello 함수는 일반 함수이므로 this 는 호출 위치에서 정의가 되면서, this는 cat 객체 데이터가 된다.

위의 코드에서 this가 명시되지 않았기 때문에 타입 에러가 발생한다.

 

interface Cat {
  name: string
  age: number
}

const cat : Cat = {
  name: 'ohzl',
  age: 27
}

function hello(this: Cat, message: string){
  console.log(`Hello ${this.name}, ${message}`)
}
hello.call(cat, 'Your are pretty awesome!') 
// 'Hello ohzl, Your are pretty awesome!'

명시적으로 this의 타입을 지정할 수 있다. ( 매개변수로 취급 X )

 

함수 - 오버로딩 (Overloading)

예시 1

function add1(a: string, b: string) {
  return a + b
}

function add2(a: number, b: number) {
  return a + b
}

add1('hello', 'world')
add2(1,2)
add1('hello', 2)  // 2 Error
add2('hello', 2)  // 'hello' Error

기본적 구조가 같은데 각각의 매개변수가 처리해야 되는 타입이 다른 경우에 함수를 나눠서 사용할 수도 있지만,

함수 오버로딩 방법을 활용하면 함수를 단순하게 관리할 수 있다.

예시 2 

function add(a: string, b: string): string		// 타입 선언 1
function add(a: number, b: number): number		// 타입 선언 2
function add(a: any, b: any) {				// 함수 구현
  return a + b
}

add('hello', 'world')
add(1,2)
add('hello', 2) 	// error 
add(1, 'world)		// error

 

문자 데이터만 받고 문자만 반환하는 타입, 숫자 데이터만 받고 숫자만 반환하는 타입 두 개가 선언되어 있으며

구현 함수에서 로직을 처리한다.

 

정리 

예시1에서 기본적인 로직과 매개변수의 이름이나 개수도 똑같은 구조의 함수를 타입이 다르다는 이유로 함수 두 개로 나뉘었는데,

함수의 오버로딩을 사용하게 되면 함수를 하나의 이름으로 만들어서 함수가 호출될 때 사용되는 타입만 분기해주면 된다.

 

타입선언 1, 타입 선언 2번에 해당하는 각각의 매개변수가 함수 구현과 일치하게 만들어줄 수 있는 방법이다.

함수 구현에 any라는 타입은 실제 타입이라기 보다는 위의 두가지 타입 선언의 내용이 어떤 방식으로든 할당이 될 수 있다라는 의미

 

 

 

 

참고

https://funes-days.com/dev/difference-of-type-alias-and-interface-in-typescript

https://guiyomi.tistory.com/109