본문 바로가기
Typescript

[TypeScript] 이펙티브 타입스크립트 정리 - 아이템 14 ~ 16

by 맨날개발 2025. 6. 14.
이펙티브 타입스크립트 읽고 정리
아이템 1 ~ 5 보러가기
아이템 6 ~ 8 보러가기
아이템 9 ~ 13 보러가기

1️⃣4️⃣ 타입 연산과 제너릭 사용으로 반복 줄이기

타입을 작성할 때도 코드 작성때와 마찬가지로 중복을 줄이는 것이 좋다. 인터페이스에서는 extends, 타입에서는 & 연산자를 통해 공통 속성에서의 확장을 통해 중복을 줄 일 수 있다.

interface Person {
	name: string;
}

interface Student extends Person {
	school: string;
}

 

타입은 자바와 달리 타입이 닫혀있지 않기 때문에 좀 더 유연하게 확장할 수 있다. 공통 속성을 잘 정의 해 놓으면 이후 타입 확장을 통해 중복 코드를 줄이기 쉽다.

 

확장하려는 타입이 항상 부모 타입의 속성을 가지는 것은 아니다. 이러한 경우에는 Pick을 사용하여 일부를 사용하면서 확장할 수 있다.

interface Action {
	name: string;
	type: string;
	prop: string;
}

type SaveAction = Pick<'name' | 'type'> & {
  data: string;
};

 

동일한 키에 값이 서로 다른 interface를 유니온으로 결합했을 때 해당 키 또한 유니온으로 결합된다.

interface A {
    name: 'A';
}

interface B {
    name: 'B';
}

type AB = A | B;
type Name = AB['name']; // 'A' | 'B'

 

제너릭 타입에서 매개변수를 제한하고 싶은 경우 extends를 사용할 수 있다. 제너릭 매개변수가 extends 다음에 오는 타입을 확장한 타입이 오도록 제한하는 것이다.

interface A {
    name: string;
}

type B<T extends A> = [T];

const b: B<{ name: string; }> = [{
    name: 'B'
}];

 

type으로 제너릭을 설정하고 함수타입을 정의할 때 제너릭의 위치에 따라 다르게 사용할 수 있다.

type A<T> = (param: T) => T;
type B = <T>(param: T) => T;

const a: A<string> = (param) => {
  return param;
}

const b: B = (param) => {
    return param;
}

const aReturn = a('');
const bReturn = b(1);
const bReturn2 = **b<string>('');**

 

A 처럼 사용하는 경우 변수에 타입을 선언할 때 제너릭으로 매개변수를 전달하여 해당 타입으로만 사용이 가능하다.

 

반면 B 처럼 사용하는 경우 함수를 선언할 때가 아닌 함수를 호출할 때 제너릭의 타입을 결정할 수 있다. 좀 더 유연하게 처리할 수 있는 방법이다.

 

이는 실제 제너릭의 대상이 무엇인지에 대한 차이이다. A는 타입 자체에 제너릭으로 설정한 것이고 B는 함수의 값에 제너릭을 설정한 것이기 때문이다.

 

1️⃣5️⃣ 아이템 15. 동적 데이터에 인덱스 시그니처 사용하기

인덱스 시그니처를 통해 객체에 모든 속성을 정의할 수 있다. 값에 어떤 속성이 올지 정확하게 파악되지 못하는 경우에는 인덱스 시그니처를 통해 타입을 정의하면 좋다. 하지만 모든 키를 받을 수 있기 때문에 정확한 타입으로 제한할 수 없다.

type A = {[property: string]: string};

 

✨ 런타임까지 속성을 알 수 없는 경우에 대해서만 인덱스 시그니처를 사용하는 것이 좋다.

 

1️⃣6️⃣ 아이템 16. number 인덱스 시그니처보다는 Array, 튜플, ArrayLike를 사용하기

자바스크립트에서 객체의 키는 모두 문자열이다. 배열도 객체이고 인덱스 또한 배열의 속성이기 때문에 실제 저장될 땐 문자열로 저장된다.

 

타입스크립트에서는 숫자를 객체의 키로 설정이 가능하다. 실제 자바스크립트에 적용될땐 숫자가 아니라 문자열이기 때문에 이는 타입상에서만 존재한다.

interface Array<T> {
    [n: number]: T;
}

만약 Array에서 제공하는 메서드를 사용하지 않고 데이터의 저장 및 길이만 사용하는 경우에는 ArrayLike를 사용하는 것도 좋다.

이 타입은 Array 타입에서 메서드를 제외하고 인덱스와 length 속성만을 가진다.

결론
number 인덱스 시그니처로 배열을 표현하는 것보다는 Array, 튜플, ArrayLike와 같은 이미 제공되는 것들이 좀 더 적합하다.