타입 추론(19 ~ 27)

ClassBinu·2024년 4월 26일

타입스크립트 초보자와 숙련자는 타입 구문의 수에서 차이가 남.
숙련된 타입스크립트 개발자는 비교적 적은 수의 구문(그러나 중요한 부분)을 사용
초보자 코드는 불필요한 타입 구문으로 도배

19. 추론 가능 타입으로 장황한 코드 방지

// 이렇게 하는 건 형편없는 스타일이다.
let x: number = 12;

// 이렇게만 해도 충분
// 왜냐면 마우스를 올려보면 이미 추론하고 있다는 걸 알 수 있음.
let x = 12;

타입 추론이 된다면 명시적 타입 구문을 필요하지 않다!
오히려 방해가 된다.

엇? 내가 생각하던 것과 완전 다르다. 난 타입스크립트에서 좋은 코드란 타입을 모두 명시하는 거라고 생각했다.

그럼 언제 타입 명시가 필요하지?

정보가 부족해서 타입스크립트가 스스로 타입을 판단하지 못하는 경우
객체 리터럴 정의할 때 쓰면 사용 순간이 아닌 할당 시점에 오류가 표시되게 함
함수 반환도 명시하면 오류를 방지할 수 있음.(정확한 위치에 오류를 표시할 수 있게 함.)

함수 반환 타입을 명시하는 이유

  • 함수에 대해 명확하게 알 수 있음.
  • 명명된 타입을 사용하기 위해.(이미 선언한 타입이 아니라 객체 형태로 타입을 추론하는 경우 방지)

20. 다른 타입에는 다른 변수 사용

기본 원칙은 타입이 바뀌는 변수는 피하는 것.
처음 값 할당 시 타입이 추론된다.
타입이 다른 값을 다룰 때는 변수를 재사용하지 않기

21. 타입 넓히기

type widening
타입 시스템이 특정 변수나 상수의 타입을 보다 넓은 범위로 자동으로 확장하는 것

let example = "Hello, World!";
// example 변수의 타입은 자동으로 string으로 추론됩니다.

타입 주석, const, 타입 단언으로 타입 넓히기를 방지할 수 있음.

22. 타입 좁히기

type narrowing

조건문

function example(input: number | string) {
    if (typeof input === "string") {
        // 이 블록 내에서 input은 'string' 타입으로 좁혀집니다.
        console.log(input.toUpperCase()); // 오류 없음
    } else {
        // 여기서 input은 'number' 타입으로 좁혀집니다.
        console.log(input.toFixed(2)); // 오류 없음
    }
}

타입 가드

interface Bird {
    fly: () => void;
}

interface Fish {
    swim: () => void;
}

function isFish(pet: Fish | Bird): pet is Fish {
    return (pet as Fish).swim !== undefined;
}

function move(pet: Fish | Bird) {
    if (isFish(pet)) {
        // Fish로 타입이 좁혀졌습니다.
        pet.swim();
    } else {
        // Bird로 타입이 좁혀졌습니다.
        pet.fly();
    }
}

타입 단언

function handleEvent(event: Event) {
    const mouseEvent = event as MouseEvent;
    console.log(mouseEvent.clientX, mouseEvent.clientY);
}

23. 한꺼번에 객체 생성

const pt = {};
pt.x = 3; // x 속성이 없습니다.
pt.y = 4;

이런 식으로 하면 pt의 타입 추론은 {}로 되기 때문에 오류가 발생함.
그래서 객체는 한 번에 추가하는 게 나음.

만약 점진적으로 객체 필드를 확장해야 한다면 개체 전개 연산자를 활용하면 됨.

const namedPoint = {...pt, ...id}

24. 일관성 있는 별칭 사용

25. 비동기 코드에서 콜백 대신 async 함수 사용

  • 콜백보다 프로미스가 코드 작성 쉬움
  • 콜백보다 프로미스가 타입 추론이 쉬움

병렬로 페이지 로드하는 함수

async function fetchPagtes() {
  const [response1, response2, response3] = await Promise.all([
    fetch(url1), fetch(url2), fetch(url3)
    ]);
}

위 코드에서 TS는 response 변수 각의 타입을 Response로 추론함.
왜냐면 fetch함수는 Response을 반환하는 걸 TS는 알고 있기 때문임.
근데 콜백 스타일로 작성하면 더 많은 코드와 타입 구문이 필요함.

프로미스보다는 async/await 구문 사용하기

  • 일반적으로 더간결하고 직관적인 코드가 됨
  • async 함수는 항상 프로미스를 반환하도록 강제됨

26. 타입 추론 문맥 이해하기

TS는 타입 추론 시 단순히 값만 고려하는 게 아니라 값이 존재하는 곳의 문맥을 살핀다.

27. 함수형 기법/라이브러리로 타입 흐름 유지

lodash
자바스크립트 생태계에서 일종의 타언어의 표준 라이브러리와 비슷한 역할

import _ from 'lodash';

const users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 40 },
  { 'user': 'barney', 'age': 34 }
];

// _.sortBy를 사용하여 사용자를 나이에 따라 정렬합니다.
const sortedUsers = _.sortBy(users, [function(o) { return o.age; }]);
console.log(sortedUsers);

0개의 댓글