My Boundary As Much As I Experienced

타입스크립트 < >(꺾쇠)를 쓰는 경우 총정리 - 제네릭(Generic), 타입 단언(Type Casting) 본문

FrontEnd/TypeScript

타입스크립트 < >(꺾쇠)를 쓰는 경우 총정리 - 제네릭(Generic), 타입 단언(Type Casting)

Bumang 2024. 5. 4. 15:37

 

1. 제네릭 타입

함수에 적용하는 경우:

함수, 인터페이스, 클래스, 타입 별칭 등에 제네릭 타입 매개변수를 지정할 때 사용된다.

<, > 안에 제네릭 타입 매개변수 (ex: K, V)를 쓰면 된다.

타입 매개변수 정리:
제네릭 타입 매개변수 (Generic Type Parameters)
T, U, V와 같은 대문자 알파벳을 사용하여 타입 매개변수를 나타낸다. 이들은 타입스크립트의 제네릭을 사용하여, 타입을 추상화하고 재사용할 수 있게 한다.

구체적 타입 (Concrete Types)
string, number, boolean 등의 원시 타입이나 더 복잡한 객체 타입 등을 직접 사용하는 경우다. 이런 경우에는 제네릭 타입 매개변수에 구체적인 타입을 대입하여 특정 타입의 값을 처리하게 된다. 예를 들어, Array<string>은 문자열만을 요소로 갖는 배열을 명시적으로 지정한다.

 

함수에 제네릭을 사용하는 예시이다.

첫 번째 T는 사용할 제네릭 매개 변수를 지정하고,

두 번째 T는 매개변수에 제네릭 변수를 지정하고,

세 번째 T는 반환값에 제네릭 변수를 지정한다.

function identity<T>(arg: T): T { // 첫 번째 T는 제네릭 선언, 두 번째 T는 매개변수에 지정, 세 번째 T는 반환값 
  return arg; 
} 

let output = identity<string>("myString"); // 여기서 <string>이 제네릭 타입 매개변수

 

아래는 복수의 제네릭을 사용하는 예이다. 

function mapKeyValue<K, V>(key: K, value: V): [K, V] { // 복수의 제네릭을 사용하는 함수
  return [key, value];
}

 

T[], U[] 같이 제네릭을 배열타입으로 활용할 수 있다.

어김없이 함수 이름 바로 옆에는 '사용할 제네릭 매개변수 자체'를 써야하고,

패러미터나 반환값에 배열 타입을 지정할 수 있다. 

function concatArrays<T, U>(array1: T[], array2: U[]): (T | U)[] {
  return array1.concat(array2);
}

 

 

타입 별칭(Type Alias)에 적용하는 경우:

타입 별칭이란?
'type' 키워드를 이용해서 만들어진 타입을 타입 별칭이라 한다. 그냥 쉽게 말해 '타입 변수'라고 생각하면 된다.
type Person = { age: number; height: number; name: string; }

 

타입 별칭에 쓰는 경우는 아래와 같다. 변수 이름 쪽에 <>를 사용해서 변수를 만들 수 있다.

type List<T> = T[];

 

다시 말하지만 주의해야할 점은, 좌변(변수 이름) 쪽에는 사용할 '제네릭 변수'만 쓸 수 있다는 것이다.

Array<T>같은 형식으로 실제로 '제네릭이 적용된 다른 형태'를 활용하려면 우변에 넣어야 한다.

// 틀린 예시
// 좌변에 복합적인 응용 타입을 사용할 순 없다. 좌변에는 담백하게 T, U같이 제네릭 매개변수 '자체'만 '선언'할 수 있다.
type List<Array<T>> = T[];

// 올바른 예시이다. 
// 좌변에는 쓸 제네릭 변수만 지정할 수 있다. 우변에서 배열에 제네릭을 넣든 객체의 일부분으로 제네릭을 넣든 응용할 수 있다.
type List<T> = Array<T>

// 틀린 예시
// 타입 선언 중에 구체적 타입을 사용할 수 없다 T, U 등의 매개변수를 써야한다.
type List<string> = "";

 

 

 

*구체적 타입은 실제 변수 선언 시에 사용가능하다.

제네릭은 클래스나 인터페이스, 타입, 함수 등을 '선언' 할 때 사용 가능하다.

let, const, var 등을 활용해서 실제 변수를 만들 때는 제네릭을 사용할 수 없다.

 

반대로 클래스나 인터페이스, 타입, 함수 등을 '선언' 할 때 변수이름 옆의 <>에 '구체적 타입'을 넣을 수 없다.

// 틀린 예시
// 타입 앨리어스 선언에 '구체적 타입'을 사용할 수 없다 T, U 등의 제네릭 매개변수를 써야한다.
type name<string> = string;

 

 

 

2. 타입캐스팅(타입 단언)

꺾쇠괄호(<, >)를 사용한 캐스팅

이 방법은 표현식 앞에 <Type>을 추가하여 타입을 캐스팅한다. 이 방식은 JSX와 같은 환경에서 사용하기에 적합하지 않을 수 있다.

let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

 

as 키워드를 사용한 캐스팅

꺾쇠 괄호를 이용하는건 아니지만 타입캐스팅에 대해 정리할 겸 추가해본다. as 키워드를 사용하는 방식은 JSX와 함께 타입스크립트를 사용할 때 권장되는 방식이다. 이 방법은 <Type> 형식의 캐스팅이 JSX 태그로 해석될 수 있는 문제를 피하기 위해 도입되었다.

 

 

정리 후기

내가 계속 타입 선언할 때 구체적 타입을 지정하려고 하거나, 실제 변수 선언 시에 제네릭 매개변수를 선언하려고 하는 등

이런 실수들을 많이 해서 이참에 정리해보았다. 이 부분이 잘 개념이 흔들리지 않아야 유틸리티 타입도 제대로 배울 수 있을 것 같다.

 

오늘 스터디를 짧게 요약하자면 아래와 같다.

 

* 타입 선언 시엔 좌변에는 담백하게 사용할 제네릭 매개변수만, 우변에는 제네릭을 활용한 타입 형태를 지정한다.

* 실제 변수 선언 시엔 제네릭을 사용하지 않고 구체적 타입을 지정한다.