성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

Typescript

타입스크립트 - 배열의 값을 타입(union)으로 바꾸기(const assertions)

제이콥(JACOB) 2019. 12. 31. 20:04

2019/12/27 - [Typescript] - 더 나은 타입스크립트 작성하기 1 - Skills에 이어, Skill적인 부분이다. 하지만 이것을 알기 전에 먼저 const assertions에 대한 개념을 알아야한다.


const assertions

 const assertions은 Typescript 3.4에서 추가된 기능이다. 새로운 리터럴을 타입을 만들 때 사용할 수 있다. 그리고 const assertions을 사용하면 Object의 경우 타입 안정성을 위해 readonly가 추가되며, 객체 리터럴은 readonly 속성을 추가되고, 배열 리터럴은 readonly 튜플이 된다. 변수 선언 자체는 let으로 하건 const로 하건 차이가 없다.

// Type: "jacob"
let str = "jacob" as const; 

// Type: readonly ["jacob", "jacob-2"]
const arr = ["jacob", "jacob-2"] as const; 

// Type: { readonly name: "jacob"; }
const obj = { name: "jacob" } as const;

 

.jsx 파일에서는 대괄호 assertions 구문도 활용할 수 있다.

// Type: "jacob"
let str = <const>"jacob";

// Type: readonly ["jacob", "jacob-2"]
const arr = <const>["jacob", "jacob-2"];

// Type: { readonly name: "jacob"; }
const obj = <const>{ name: "jacob" };

주의할 점

 간단한 리터럴 표현식(enum members, string, number, boolean, array, or object literal)에만 적용할 수 있다.

그리고 const context는 이제 변경할 수 없다.

let arr = [1, 2, 3, 4];

let foo = {
  name: "foo",
  contents: arr
} as const;

foo.name = "bar"; // error!
foo.contents = []; // error!
foo.contents.push(5); // ...works!

const assertions을 이용해서 배열 값으로 구성된 union 타입 만들기

 객체를 타입으로 만드는 거는 쉽기도 하고 관련 내용이 많지만, 배열을 만드는 법은 잘 없어서 올려본다. 일단 우리에게 아래와 같은 배열이 있다고 해보자.

const names = ['jacob', 'master jung', 'kyuhyun'];


 그리고 나는 이제 names에 있는 값들로 이루어진 타입은 만들고 여러 로직에서 활용하고 싶은 것이다. 아마도 내가 원하는 타입은 이런 게 아닐까 싶다.

type Names = 'jacob' | 'master jung' | 'kyuhyun';

자 이제, 위에 있는 타입을 const assertions을 이용해서 만들어 보자.

const names = ['jacob', 'master jung', 'kyuhyun'] as const;
type Names = typeof names[number];


이게 끝이다. 물론 여기서 const assertions을 안쓴다고 에러가 나지는 않지만, 타입 추론이 제대로 되지 않는다. 이유는 const assertions이 없다면 객체의 경우 언제든지 값이 바뀔 수 있어 타입 안정성이 보장되지 않기 때문이다.

 

반응형