#26 타입 추론에 문맥이 어떻게 사용되는지 이해하기

2023. 2. 14.·🎨 프론트엔드 공부/JS & TS

이펙티브 타입스크립트 (댄 밴더캄 지음) 를 읽고 정리

📍요약

✅변수를 뽑아서 별도로 선언했을 때 에러가 발생한다면 타입 선언을 추가해야한다

✅변수가 정말 상수라면 상수 단언(at const)을 사용해야 한다

- 단, 상수 단언을 사용하면 정의한 곳이 아닌, 사용한 곳에서 에러가 발생할 수 있으므로 주의

 

📍튜플 사용시 타입 추론 과정에서 유의점

타입스크립트의 튜플이 배열을 만드는 [] 를 같이 사용하기 때문에 배열로 혼동되는 에러가 발생할 수 있다

- 예시

// Parameter is a (latitude, longitude) pair.
function panTo(where: [number, number]) { /* ... */ }

panTo([10, 20]);  // OK

const loc = [10, 20];
panTo(loc); // 타입이 튜플이 아닌 number[] 이므로 에러 발생
//    ~~~ Argument of type 'number[]' is not assignable to
//        parameter of type '[number, number]'

 

[10, 20] 은 튜플(길이가 고정)이기도 하지만, 배열(길이가 정해지지 않음)이기도 하다

- 따라서 타입 추론시 우선 number[]로 추론된다

 

이 문제가 string과 리터럴 타입인 경우에는 const 키워드를 사용하여 해결할 수 있다

그런데 const는 이미 사용했다. 어떻게 해결할 수 있을까?

 

⭐타입스크립트가 타입을 추론하지 않도록 타입 선언을 제공하면 된다

const loc: [number, number] = [10, 20];

 

⭐또 다른 해결방법은 at const를 붙여 상수 문맥을 제공하는 것이다

- const는 단지 그 값이 가리키는 참조가 변하지 않는 얕은(shallow) 상수

- as const는 그 값이 내부까지 (deeply) 상수 -> readonly 붙임

 

그래서 일차적으로는 타입 에러가 발생한다

- as const 를 사용한 readonly [10, 20] 가 과도하게 정확하기 때문이다

- pan 함수의 매개변수의 타입은 단지 [number, number] 튜플이므로 [10, 20] 대신 [20, 30] 도 가능

 

더 깊게 들여다보면

- [10, 20] as const (튜플)은 엄밀히 ReadonlyArray가 된다

(Array의 부분집합)

- ReadonlyArray 타입에 Array 타입을 할당하는 것은 가능하나 그 역은 성립 X

 

- 예시

// Parameter is a (latitude, longitude) pair.
function panTo(where: [number, number]) { /* ... */ }
const loc = [10, 20] as const; // 타입 : readonly [10, 20]
panTo(loc);
   // ~~~ Type 'readonly [10, 20]' is 'readonly'
   //     and cannot be assigned to the mutable type '[number, number]'

 

해결책 2가지를 떠올려볼 수 있다

1️⃣panTo 함수 매개변수인 where에 readonly를 부여한다

- 예시

function panTo(where: readonly [number, number]) { /* ... */ }
const loc = [10, 20] as const;
panTo(loc);  // OK

 

2️⃣별도의 타입구문을 사용한다

- 예시

type WhereType = [number, number];

function panTo(where: WhereType) { /* ... */ }
const loc: WhereType = [10, 20];
panTo(loc);  // OK

 

📍객체 사용시 타입 추론 과정에서 유의점

- 객체에서도 타입 추론시 비슷한 문제를 찾을 수 있다

type Language = 'JavaScript' | 'TypeScript' | 'Python';
interface GovernedLanguage {
  language: Language;
  organization: string;
}

function complain(language: GovernedLanguage) { /* ... */ }

complain({ language: 'TypeScript', organization: 'Microsoft' });  // OK

const ts = {
  language: 'TypeScript',
  organization: 'Microsoft',
};
complain(ts); // ts의 language 프로퍼티의 타입이 달라서 에러 발생
// ts의 타입
// const ts: {
//     language: string;
//     organization: string;
// }

 

이 문제도 타입 선언을 추가하거나, 상수 단언 (as const)을 사용하여 해결할 수 있다

type Language = 'JavaScript' | 'TypeScript' | 'Python';
interface GovernedLanguage {
  language: Language;
  organization: string;
}

function complain(language: GovernedLanguage) { /* ... */ }

complain({ language: 'TypeScript', organization: 'Microsoft' });  // OK

// 1. 타입 선언 추가
const ts1: GovernedLanguage = {
  language: 'TypeScript',
  organization: 'Microsoft',
};
complain(ts1); // OK

// 2. 상수 단언 추가
const ts2 = {
  language: 'TypeScript',
  organization: 'Microsoft',
} as const;
complain(ts2); // OK

 

객체 as const는 여전히 Object 타입

(튜플의 경우 as const 사용하면 ReadonlyArray로 바뀜)

 

'🎨 프론트엔드 공부/JS & TS' 카테고리의 다른 글
  • #30 문서에 타입 정보를 쓰지 않기
  • #27 함수형 기법과 라이브러리로 타입 흐름 유지하기
  • #25 비동기 코드에는 콜백 대신 async 함수 사용하기
  • #24 일관성 있는 별칭 사용하기
지식물원
지식물원
지식이 자라는 식물원!
  • 지식물원
    지식물원
    지식물원
  • 전체
    오늘
    어제
    • 분류 전체보기 (510)
      • 🎨 프론트엔드 공부 (247)
        • JS & TS (86)
        • HTML & CSS (22)
        • React & Next (49)
        • Vue & Nuxt (22)
        • 기타 (68)
      • 🤓 기술 학습 & 공부 기록 (116)
        • Node.js (0)
        • Python (37)
        • 백엔드 (0)
        • 딥러닝 (1)
        • 컴퓨터 일반 (72)
        • 개발 인프라 (6)
      • 👨‍💻 프로젝트 경험 (6)
        • Work (0)
        • Toy (6)
      • ⚙️ 개발 팁 & 노하우 (21)
        • 프론트엔드 (6)
        • 기타 (15)
      • ☕️ 커리어 & 인터뷰 준비 (88)
        • 코딩 테스트 (88)
      • 📰 기술 트렌드 & 생각 정리 (4)
      • 📚 기타 (25)
        • 마케팅 (15)
        • 비개발서적 (10)
  • 블로그 메뉴

    • 태그
  • 링크

  • 공지사항

    • 모바일 접속 시 코드 하이라이팅 깨질 때
  • 인기 글

  • hELLO· Designed By정상우.v4.10.3
지식물원
#26 타입 추론에 문맥이 어떻게 사용되는지 이해하기
상단으로

티스토리툴바