📎아이템 44 타입 커버리지를 추적하여 타입 안전성 유지하기

noImplicitAny를 설정하고 암시적 any 대신 명시적 타입 구문을 추가해도 any 타입과 관련된 문제들로부터 안전하다고 할 수 없다. any 타입이 여전히 프로그램 내에 존재할 수 있는 두 가지 경우가 있다.

🍙 명시적 any 타입

any 타입의 범위를 좁히고 구체적으로 만들어도 여전히 any 타입이다. 특히 any[]와 {[key : string] : any} 같은 타입은 인덱스를 생성하면 단순 any가 되고, 코드 전반에 영향을 미친다.

🍙 서드파티 타입 선언

@types 선언 파일로부터 any 타입이 전파되기 때문에 특별히 조심해야 한다. noImplicitAny를 설정하고 절대 any를 사용하지 않았다고 하더라도 여전히 any 타입은 코드 전반에 영향을 미친다.

⭐️ any 타입은 타입 안전성과 생산성에 부정적 영향을 미칠 수 있으므로 프로젝트에서 any의 개수를 추적하는 것이 좋다.

npm의 type-cover-age 패키지를 활용하여 any를 추적할 수 있는 방법이 있다. (any의 근원지를 찾을 수 있다.)

📍 코드에 any가 남아있는 이유

오류를 간단히 해결하기 위해 명시적으로 any를 선언한 경우

  • 타입 오류가 발생했지만 해결하는데 시간을 쏟고 싶지 않아서.

  • 아직까지 타입을 제대로 작성하지 않아서.

  • 급하게 작업하느라 any를 그대로 나둔 경우.

📍 any가 등장하는 몇 가지 문제와 해결책

🔗 표 형태의 데이터에서 어떤 종류의 열 정보를 만들어내는 함수

function getColumnInfo(name: string): any {
  return utils.buildColumnInfo(appState.dataSchema, name);  // Returns any
}

utils.buildColumnInfo 호출은 any를 반환한다. → 주석과 함께 명시적으로 : any 구문을 추가했다.

추후에 타입 정보를 추가해도 함수의 반환문에 있는 any 때문에 모든 타입 정보가 날라가게 된다.

🔗 서드파티 라이브러리로부터 비롯되는 any 타입

✓ 가장 극단적인 예는 전체 모듈에 any 타입을 부여하는 것이다.

declare module 'my-module';

'my-module'에 어떤 것이든 오류 없이 임포트 할 수 있다. 임포트한 모든 심벌은 any 타입이고, 임포트한 값이 사용되는 곳마다 any 타입을 양산하게 된다.

import {someMethod, someSymbol} from 'my-module';  // OK

const pt1 = { x: 1, y: 2 };
//    ^? const pt1: { x: number; y: number; }
const pt2 = someMethod(pt1, someSymbol);  // OK
//    ^? const pt2: any

일반적인 모듈의 사용법과 동일하기 때문에, 타입 정보가 모두 제거됐다는 것을 간과할 수도 있다. (해당 모듈을 점검해야 하는 일이 생긴다.)

✓ 타입에 버그가 있는 경우

선언된 타입과 실제 반환된 타입이 맞지 않는 경우 어쩔 수 없이 any 단언문을 사용해야 한다. 나중에 라이브러리가 업데이트 되어 함수의 선언문이 제대로 수정된다면 any를 제거해야 한다.

📍 정리

any 타입이 사용되는 코드가 실제로는 더 이상 실행되지 않는 코드 일 수도 있고, 어쩔 수 없이 사용된 any를 개선하여 제대로 된 타입으로 바뀌면 더 이상 any가 필요 없어진다. 버그가 있는 타입 선언문이 업데이트 되어 제대로 된 타입 정보를 가질 수도 있다.

타입 커버리지를 추적하면 이러한 부분들을 쉽게 발견할 수 있기 때문에 코드를 꾸준히 점검할 수 있게 해준다.

📍 요약

  • noImplicitAny가 설정되어 있어도, 명시적 any 또는 서드파티 타입 선언(@types)를 통해 any 타입은 코드 내에 여전히 존재할 수 있음을 주의하자.

  • 작성한 프로그램의 타입이 얼마나 잘 선언되었는지 추적해야 한다. 추적함으로써 any의 사용을 줄여 나갈 수 있고, 타입 안전성을 꾸준히 높일 수 있다.

Last updated