TypeScript 4.9 미리보기

우동이·2022년 10월 10일

TypeScript

목록 보기
1/2
post-thumbnail
  • 아직 베타 버전이며 정식 릴리즈는 11월 예정입니다!
  • npm install -D typescript@beta 스크립트를 활용해 미리 체험할 수 있으며 주요 내용을 요약하고자 합니다.

1. satisfies 키워드

  • satisfies 키워드는 as 키워드보다 더 안전한 upCasting을 지원하며 object의 key / value에 대해서도 upCasting을 지원하는 키워드 입니다.

1) 기존 Object upCasting

type Colors = 'red' | 'green' | 'blue';
type RGB = [red: number, green: number, blue: number];

export const palette: Record<Colors, string | RGB> = {
  red: [255, 0, 0],
  green: '#00ff00',
  blue: [0, 0, 255],
};

// palette.red에 접근했음에도 불구하고 string or RGB으로 추론됩니다.
const redComponent = palette.red

2) satisfies 키워드 활용

type Colors = 'red' | 'green' | 'blue';
type RGB = [red: number, green: number, blue: number];

const palette = {
    red: [255, 0, 0],
    green: "#00ff00",
    bleu: [0, 0, 255]
} satisfies Record<Colors, string | RGB>;

// key / value 각각에게 부여된 타입들을 추론 가능
// red: RGB
const red = palette.red.at(0);
// green: string
const green = palette.green.toUpperCase();
  • object에 허용된 key값만 들어오도록 활용할 수 있습니다.
type Colors = "red" | "green" | "blue";

const favoriteColors = {
    "red": "yes",
    "green": false,
    "blue": "kinda",
    "white": false
// 에러 발생 => 허용되지 않은 white key 존재
} satisfies Record<Colors, unknown>;
  • object의 key 중에서 특정 key에만 접근을 강제할 수 있게 되며 더 안전한 타입 제한이 가능합니다.
// as 키워드도 name 프로퍼티만 접근 가능하도록 제한 가능
const object_as = {
  key: { name: 'a', age: 90 } as { name: string; },
};

// 기존의 as 키워드에서는 phone 프로퍼티가 없어도 강제로 타입지정이 가능 => 휴먼 에러 증가
const object_as = {
  key: { name: 'a', age: 90 } as { name: string; age: number; phone: string },
};

// satisfies 키워드로 name 프로퍼티만 접근 가능하도록 제한 가능 => 안전성 증가
const object_satisfies = {
  key: { name: 'a', age: 90 } satisfies { name: string; },
};

// satisfies 키워드에서는 phone 프로퍼티가 없을 경우 에러 발생
const object_satisfies = {
  // 에러 발생
  key: { name: 'a', age: 90 } satisfies { name: string; age: number; phone: string },
};

2. in 연산자 성능 개선

  • 기존의 자바스크립트 in연산자를 이용해 객체에 특정 속성이 존재하는지 확인할 수 있었으며 해당 기능을 이용해 타입가드로 활용할 수 있었습니다.
interface RGB {
  red: number;
  green: number;
  blue: number;
}

interface HSV {
  hue: number;
  saturation: number;
  value: number;
}

export function setColor(color: RGB | HSV) {
  if ('hue' in color) {
    // color는 HSV 타입으로 추론
    const HSV = color;
  }
  // ...
}
  • 또한 in 연산자 왼쪽에 올 수 있는 타입은 object의 key값으로 지정가능한 any | string | number | symbol 타입만 가능했습니다.
const example: any = {};

// 가능
if ('key' in example) {
}

// 불가능 => 에러 발생
if ({} in example) {
}
  • 하지만 아래처럼 함수를 만들어서 인자를 받을 경우 에러가 발생하지 않았습니다.
    • TypeScript 4.9를 사용하게 되면 key 부분에서 에러가 발생하게 됩니다.
    • in 연산자의 내부 성능을 개선하여 key타입을 더 명확하게 판별할 수 있도록 개선
const example: any = {};

function isCheck<T>(key: T, example: any) {
  // TypeScript 4.9 => key 부분에서 에러 발생
  if (key in example) {
    return true;
  }

  return false;
}

// 에러 발생x
isCheck({}, example);
  • 현재 TypeScript 4.8에서 keyof any로 타입을 강화하면 해결할 수 있습니다.
    • keyof any: string | number | symbol
const example: any = {};

function isCheck<T extends keyof any>(key: T, examples: any) {
  if (key in examples) {
    return true;
  }

  return false;
}

// 에러 발생 => string | number | symbol 허용!
isCheck({}, example);

3. NaN Check 사용성 개선

  • 기본적으로 NaN은 숫자가 아니라는 값을 의미하며 값은 산술 연산이 정의되지 않은 결과 또는 표현할 수 없는 결과를 의미하기도 합니다.
  • 아래와 같이 일반적인 비교연산자를 활용해보면 어떠한 타입과도 false를 반환합니다.
console.log(NaN == 0)  // false
console.log(NaN === 0) // false

console.log(NaN == NaN)  // false
console.log(NaN === NaN) // false

console.log(NaN == 'a')  // false
console.log(NaN === 'a') // false
  • 그래서 기본적으로 자바스크립트에서 제공하는 엄격한 검사를 제공하는 Number.isNaN를 자주 사용하게 됩니다.
    • Number.isNaN은 비교하기전 강제로 숫자로 변환하지 않습니다.
    • 주어진 값의 유형이 Number이고 값이 NaN이면 true, 아니면 false를 반환합니다.
Number.isNaN(NaN); // true
Number.isNaN(0 / 0); // true

Number.isNaN("abc"); // false
Number.isNaN(null); // false
Number.isNaN("37"); // false
  • 하지만 무의식적으로 value === NaN 처럼 비교연산자를 활용하여 휴먼에러가 발생하는 경우가 있습니다.
  • TypeScript 4.9에서는 아래처럼 NaN을 직접 비교한다면 Number.isNaN를 사용하라고 에러를 발생시킵니다.
    • 사실 esLint를 활용한다면 TypeScript 4.9를 사용하지 않아도 해결할 수 있습니다!
function validate(value: number) {
    // 에러발생 => This condition will always return 'true'
    // Did you mean '!Number.isNaN(ㅍalue)'?
    return value !== NaN;
}

참고 링크

profile
아직 나는 취해있을 수 없다...

0개의 댓글