woowacourse-study / 2022-thanks-giving-effective-typescript

🍂추석 연휴 집중🍂 이펙티브 타입스크립트를 읽는 모임 (✌️완주완료✌️)
6 stars 0 forks source link

2022.09.07 #4

Closed prefer2 closed 2 years ago

prefer2 commented 2 years ago

타스 꽤나 재미있는 녀석일지도?

moonheekim0118 commented 2 years ago

변경 관련된 오류를 방지하기 위해 readonly 사용하기

Readonly 배열의 특징

얕게 (shallow) 동작하는 readonly

readonly string[][]; // 1번

(readonly string[])[]; //2번

const 와 readonly 의 차이

추론 가능한 타입을 사용해 장황한 코드 방지하기

타입스크립트는 타입추론을 잘 해준다. 하지만 타입 추론을 잘해줌에도 불구하고, 명시적으로 타입핑을 해야할 때는 언제일까?

1. 객체 리터럴을 정의할 떄

why

2. 함수의 반환값을 정의 할 때

why

prefer2 commented 2 years ago

동적 데이터에 인덱스 시그니처 사용하기

type Rocket = { [property: string] : sring };
const rocket: Rocket {
    name: 'Falcon 9;,
    variant: 'v1.0',
    thrust: '43390 kN'
}

인덱스 시그니처

단점

인덱스 시그니처는 동적 데이터를 표현할 때 사용한다.

어떤 타입에 가능한 필드가 제한되어 있는 경우에는 인덱스 시그니처를 사용하지 말아야 한다.

interface Row1 { [column: string]: number } // 너무 광범위하다

// Record 사용
type Vec3D = Record<'x' | 'y' | 'z', number>;

// 매핑된 타입 사용
type Vec3D_v2 = {[k in 'x' | 'y' | 'z']: number};

type ABC = {[k in 'a' | 'b' | 'c']: k extends 'b' ? string : number};

Record는 키 타입에 유연성을 제공하는 제너릭 타입이다.

매핑된 타입을 통해서도 모델링 가능. 키마다 별도의 타입을 사용할 수 있다.

그럼 언제 인덱스 시그니처를 사용할까? → 런타임 때까지 객체의 속성을 알 수 없을 때. 단 안전한 접근을 위해 인덱스 시그니처의 값 타입에 undefined를 추가하는 것을 고려해야 한다.

number 인덱스 시그니처보다는 Array, 튜플, ArrayLike 사용하기

자바스크립트에서 배열은 객체이다. 객체에서 숫자는 키로 사용할 수 없다. 키로 숫자를 사용하고자 하면 자바스크립트 런타임은 이를 문자열로 변환한다. Object.keys를 이용해 배열의 키를 나열해 보면, 키가 문자열로 출력된다.

타입스크립트는 혼란을 바로잡기 위해 객체에서 숫자 키를 혀용하고, 문자열 키와 다른 것으로 인식한다. 다만 이는 타입스크립트에서만 일어나는 일이고 실제 런타임에 사용되는 키는 string 타입이다.

변경 관련된 오류 방지를 위해 readonly 사용하기

readonly 접근 제어자

number[]는 readonly number[]보다 기능이 많다. 즉 readonly number[]의 서브타입이다. 따라서 변경 가능한 배열을 readonly 배열에 할당할 수 있다. 하지만 그 반대는 불가능하다.

매개변수를 readonly로 선언하면

readonly를 붙이는 명시적인 방법을 사용하는 것이 컴파일러와 사람 모두에게 좋다.

어떤 핫무를 readonly로 만들면, 그 함수를 호출하는 다른 함수도 모두 readonly로 만들어야 한다. 라이브러리에 있는 함수를 호출한다면 타입 선언을 바꾸지 못하므로 타입 단언문을 사용해야 한다.

readonly는 얕게(shallow) 동작한다

const dates: readonly Date[] = [new Date()];
dates.push(new Date()); // push 형식이 없습니다
dates[0].setFullYear(2037); // 정상
liswktjs commented 2 years ago

타입과 인터페이스의 차이점 알기

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

soyi47 commented 2 years ago

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

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

const rocket: Rocket = {
    name: 'Falcon 9',
    variant: 'v1.0',
    thrust: '4,940 kN',
};  // 정상