본문으로 바로가기
Nested Extends

NextApiRequest와 AxiosInstance의 타입을 수정할 일이 생겨

인터페이스를 extends하면서 nested 멤버에 대해 접근하는 방법이 필요했다.

 

interface MomInterface{
  nestedObject:{
    nestedValue: string;
  }
}

interface ChildInterface extends MomInterface{
  nestedObject: MomInterface['nestedObject']& {
    test: string;
  }
};

일단은 이렇게 MomInterface를 extends한 다음, 수정할 멤버 'nestedObject'에 MomInterface['nestedObject']를 붙이는 방법을 생각했다.

 

그러나 조금 MomInterface를 두번이나 적어야하는 점이 마음에 들지 않는다.

만약 수정할 멤버들이 많아진다면 그만큼 MomInterface를 중복해서 적어야한다.

type ChildInterface2 = MomInterface &{
  nestedObject : {
    test:string
  }
}

이를 type을 통해서 구현하면 훨씬 깔끔하게 작성할 수 있다.

 

Non-null Assertion Operator

Non-null Assertion Operator는 타입이 Null, undefined가 아니라고 단언해주는 역할을 한다.

 

function splitInHalf(str: string | null) {
    let checkString = function () {
        if (str == null || str == undefined) {
            str = "test";
        }
    }
    checkString();
    return str!.substring(0, str!.length / 2);
}

let s = splitInHalf("bean");
console.log(s);

위와 같은 경우 str은 "test"라는 값이 할당이 되지만 타입스크립트에서는 이에 대해서는 추론하지 못한다.

 

따라서 str이 null이 아니라는 것을 타입스크립트에게 힌트를 주기 위해 ! 연산자를 사용하는 것이다.

 

그러나 ESLint에서는 Non-null Assertion Operator를 사용하는 것은 strict null checking의 이점을 얻지 못한다는 점에서 이를 허용하지 않고 있다.

 

즉 !을 써서 타입 단언을 하는건 Null Checking을 너무 쉽게 피해갈수 있으므로 결과적으로 위험하기 떄문에 막아놓은 것이다.

interface Foo {
  bar?: string;
}

const foo: Foo = getFoo();
const includesBaz: boolean = foo.bar!.includes('baz');

위와 같이 ! Operator를 사용한 코드는

 

interface Foo {
  bar?: string;
}

const foo: Foo = getFoo();
const includesBaz: boolean = foo.bar?.includes('baz') ?? false;

이런식으로 구현할 수 있다.

 

위와 같은 코드는 Null 단언이 아니라, Optional Chaining을 통해서 Null/undefined인 경우에 fallback case인 false를 반환하는 식으로 조금 더 안전하게 구현할 수 있다.

 

foo.bar?.includes('baz')는

foo.bar == null ? undefined : foo.bar.includes('baz);

와 동일하며 Null Check을 조금 더 깔끔하게 작성할 수 있도록 도와준다.

 

Nullish Coalescing

기존에는 OR 연산자 ||을 통해서 default처리를 해왔다.

 

let a = someValue || defaultValue;

그러나 OR연산자를 사용하면서 생기는 문제는 자바스크립트는 Falsy한 밸류와 null/undefined를 명확하게 구분하지 않는다는 것이다.

 

만약 '', 0 등이 someValue에 들어왔다면 자바스크립트는 이를 거짓으로 보고 defaultValue를 호출한다.

 

이것은 떄론 문법의 자유도를 보장해줄때도 있겠지만, 떄로는 의도치 않은 defaultValue 호출을 하는 등 예기치 못한 버그를 발생할 수 있다.

 

이런 것을 해결해주는 것이 Nullish Coalescing Operator  ??다.

 

이 연산자는 Null과 undefined에 대해서만 구분하여 의도치 않은 동작을 방지할 수 있다.

 

result = a ?? b
result = (a !== null && a !== undefined) ? a : b;

 

 

foo.bar?.includes('baz') ?? false;

이 코드를 단계별로 보자면

 

foo.bar?.includes('baz')에서 만약 foo.bar가 null/undefined라면 ? 연산자에 의하여 undefined가 반환되고,

?? 연산자에 의하여 첫 항이 undefined므로 false를 리턴한다.

 

?와 ?? 연산자를 통해서 Null Check와 Default Value 설정을 깔끔하게 구성할 수 있는 것이다.