ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Typescript 5.3 베타 요약
    Study/개발 2023. 10. 11. 22:38

    원문 링크: https://devblogs.microsoft.com/typescript/announcing-typescript-5-3-beta/

    목록

    클릭 시 원문의 해당 항목으로 이동합니다.

    Typescript 5.3 버전 베타가 10월 3일에 공개되었다.
    해당 버전은 "feature-stable" 버전이라고 하며, 개발 목표는

    1. 버그 픽스
    2. 정리 (polish)
    3. 위험도 낮은 에디터 기능 개발

    이라고 한다.

    몇가지 신규 기능 및 픽스에 대해서 정리해봤다.

    상호작용 가능한 Inlay Type Hint

    타입 힌트에서 Go to Definition이 가능하여 더 쉬운 네비게이션이 가능해졌다.

    타입 힌트

    switch (true) Narrowing

    switch (true) 구문에서 기존에는 case 절 안의 type narrowing이 동작하지 않았다.
    아래 캡쳐를 보면 if(...) 에서는 동작하지만 switch(true) case ... 내에서는 오류가 발생한다.

    switch(true) 추론 오류

    이제 위와 같은 상황에서도 type narrowing이 동작한다.

    Boolean 비교에서의 Narrowing

    interface A {
        a: string;
    }
    
    interface B {
        b: string;
    }
    
    type MyType = A | B;
    
    function isA(x: MyType): x is A {
        return "a" in x;
    }
    
    function someFn(x: MyType) {
        // if (isA(x)) {...}로 작성하면 원래 동작했다.
        if (isA(x) === true) {
            console.log(x.a); // x가 A로 추론됨!
        }
    }

    if 문 내에서 Boolean과 직접 비교하는 방식을 사용하기도 하는데, 기존에는 이렇게 하는 경우 if문 내에서 타입 Narrowing이 동작하지 않았다.
    이제 동작하도록 수정되었다.

    super 프로퍼티의 Instance 필드에 대한 접근 확인

    클래스 내에서 super 프로퍼티를 통해 상위 클래스의 메서드에 접근할 수 있다.

    class Base {
        someMethod() {
            console.log("someMethod called!");
        }
    }
    
    class Derived extends Base {
        someOtherMethod() {
            super.someMethod();
        }
    }
    
    new Derived().someOtherMethod(); // 가능

    그러나 인스턴스 필드에 접근할 수는 없다.
    프로토타입에 선언되는 메서드에만 접근 가능하다.

    하지만 아래의 경우 기존 타입스크립트에선 에러를 잡아내지 못했다.

    class Base {
        someMethod = () => {
            console.log("someMethod called!");
        }
    }
    
    class Derived extends Base {
        someOtherMethod() {
            super.someMethod();
        }
    }
    
    new Derived().someOtherMethod();

    실행 결과
    인스턴스 메서드 실행 오류

    5.3 버전에선 해당 오류를 잡아낼 수 있다.

    Symbol.hasInstance를 통한 instanceof type narrowing

    Symbol.hasInstance는 instanceof 연산의 동작을 오버라이드한다.
    기존에는 A instanceof X가 true인 경우 A의 타입은 instanceof가 override 됐는지에 상관 없이 X로 판단되었다.

    이 때, 아래와 같은 상황의 오류가 발생할 수 있다.

    interface PointLike {
        x: number;
        y: number;
    }
    
    class Point implements PointLike {
        x: number;
        y: number;
    
        constructor(x: number, y: number) {
            this.x = x;
            this.y = y;
        }
    
        distanceFromOrigin() {
            return Math.sqrt(this.x ** 2 + this.y ** 2);
        }
    
        static [Symbol.hasInstance](val: unknown): val is PointLike {
            return !!val && typeof val === "object" &&
                "x" in val && "y" in val &&
                typeof val.x === "number" &&
                typeof val.y === "number";
        }
    }
    
    
    function f(value: unknown) {
        if (value instanceof Point) {
            // x, y에 접근할 수 있는 것은 맞다.
            value.x;
            value.y;
    
            // 하지만 instanceof는 distanceFromOrigin의 유무를 알려주지 못한다.
            // hasInstance 정의에서 알 수 있듯이 PointLike인 것만 알 수 있다.
            // 아래 코드는 에러가 발생할 수 있다.
            value.distanceFromOrigin();
        }
    }

    5.3 버전에서는 위의 경우에서 value에 대해 PointLike라고 판단하여 오류를 잡아낼 수 있다.

    기타

    JSDoc 파싱 스킵을 통한 최적화

    tsc를 실행할 때 JSDoc에 대한 파싱을 스킵할 수 있게 되었다.
    JSDocParsingMode 속성을 사용.

    Intersection 최적화

    A & (B | C) 의 경우 TS는 (A & B) | (A & C)로 바꾼 후 타입을 판단한다.
    이 경우, A & (B | C | ... | ZZZ)로 union 파트가 길어지면 연산이 느려질 수 있다.
    A인지를 판별하기 위해 위 식을 (A & B) | (A & C) | ... | (A & ZZZ) 형태로 전개 후 각각에 대해 비교하기 때문.
    기존 포맷을 유지한 상태로 A인지를 판별한다면 바로 A가 intersection 되어 있는 것을 알 수 있다.
    이 사실을 이용해서 해당 케이스에 대한 최적화가 추가되었다.

    tsserverlibrary.js와 typescript.js 병합

    중복되는 부분들에 대해 병합처리, 타입스크립트 패키지 사이즈가 감소했다.

    위 언급한 내용들 외에, 전체 개선점 및 관련 깃헙 이슈 등을 보고 싶다면 글 상단의 원문 링크로 갈 수 있다.

    728x90
Designed by Tistory.