본문 바로가기
Javascript & Typescript

[Typescript] any 타입을 가능한 좁은 범위에서 사용하기

by 이곳느 2022. 1. 7.
이 글은 '이펙티브 타입스크립트' 책의 내용을 정리한 글입니다.

any 타입은 가능한 한 좁은 범위에서만 사용하기

먼저 함수와 관련된 any의 사용법을 살펴봐야 합니다.

function processBar(b: Bar) {/*...*/}

function f1 () {
    const x = expressionReturningFoo();
    processBar(x); // ~ 'Foo' 형식의 인수는 'Bar' 형식의 매개변수에 할당 될 수 없음
}

문맥상으로 `x`라는 변수가 동시에 `Foo` 타입과 `Bar` 타입에 할당 가능하다면, 오류를 제거하는 방법은 두 가지 입니다.

function f2() {
    const x: any = expressionReturningFoo(); // 이렇게 하면 안됩니다.
    processBar(x);
}

function f3() {
    const x = expressionReturningFoo();     // 이게 낫습니다.
    processBar(x as any);
}

두 가지 해결책 중에서 `f2` 에 사용된 `x: any` 보다 `f3` 에 사용된 `x as any` 형태가 권장됩니다.

이유는 `any` 타입이 `processBar` 함수의 매개변수에서만 사용된 표현식이므로 다른 코드에는 영향을 미치지 않기 때문입니다.

`f2` 에서는 함수의 마지막까지 `x` 의 타입이 `any` 인 반면, `f3` 에서는 `processBar` 호출 이후에 `x` 가 그대로 `Foo` 타입입니다.

만약 `f2` 함수가 `x` 를 반환한다면 문제가 커집니다.

예를 들면 아래와 같습니다.

function f4() {
    const x: any = expressionReturningFoo();
    processBar(x);
    return x;
}

function g() {
    const foo = f1();       // 타입이 any
    foo.fooMethod();        // 이 함수 호출은 체크되지 않음
}

`g()` 내에서 `f4()` 가 사용되므로 `f4()` 의 반환 타입인 `any` 타입이 `foo` 의 타입에 영향을 미칩니다.

이렇게 함수에서 `any` 를 반환해버리면 그 영향력은 프로젝트 전반에 퍼지게 됩니다.

반면 `any` 의 사용 범위를 좁게 제한하는 `f3` 함수를 사용한다면 `any` 타입이 함수 바깥으로 영향을 미치지 않습니다. 비슷한 관점으로 TS에서 함수의 반환 타입을 추론할 수 있는 경우에도 반환 타입을 반드시 명시하는게 좋습니다.

함수의 반환타입을 명시하면 `any` 타입이 함수 바깥으로 영향을 미치는 것을 방지할 수 있습니다.

객체에서는?

const config1: Config = {
    a: 1,       // 이 속성은 체크되지 않음
    b: 2,       // 이 속성은 체크되지 않음
    c: {
        key: 'value'
    }
} as any

const config2: Config = {
    a: 1,       // 이 속성은 체크 됨
    b: 2,       // 이 속성은 체크 됨
    c: {
        key: 'value' as any
    }
}

객체에서도 마찬가지 입니다. 객체 전체를 `any` 로 타입 단언해버리면 다른 속성들(a와 b) 역시 타입 체크가 되지 않는 부작용이 생깁니다. 그러므로 다음 코드처럼 최소한의 범위에만 `any` 를 사용하는 것이 좋습니다.

'Javascript & Typescript' 카테고리의 다른 글

JS Garbage Collection  (0) 2022.01.02
JS - Function  (0) 2020.07.21
JS - Object  (0) 2020.07.21
프레임워크란?  (0) 2020.03.26