타입스크립의 장점이 강력한 타입시스템을 통해 컴파일 타임에 타입 검사를 통해 오류를 검출할 수 있다는 점이다.
가끔 타입을 string, nubmer, Pesron 과 같은 평범한(?) 타입이 아닌 특정 값만을 취할 수 있는 타입을 선언해서 쓸 경우가 있다.
예를 들어, 파일의 확장자를 이미지와 관련된 파일만 받을 수 있다고 해 보자. ext 변수는 'jpg' 또는 'gif' 문자열만 받을 수 있다.
let ext: 'jpg' | 'gif' = 'bmp'; // 구문 오류
이를 별도의 타입으로 선언할 수 있다.
type Ext = 'jpg' | 'gif';
let ext: Ext = 'gif';
나아가 요청으로 받은 데이터의 유효성 검사를 하고 싶다고 하자. 예를 들어 인터페이스를 통해 받은 파일을 표현하는 데이터가 있고 이를 나타내는 FileDto 클래스가 있다.
class File {
ext: Ext;
}
ext를 위해서 정의한 타입으로 선언했다. 'bmp'
문자열을 받았을 때 400 에러를 내도록 처리하도록 하려면 어떻게 해야할까? class-validator를 활용해서 다음처럼 하면 좋겠다.
class File {
@IsExt()
ext: Ext;
}
하지만 이 방법은 @IsExt 데커레이터를 따로 구현해야 하는 번거로움이 있다.
튜플 리터럴을 유니언 타입으로 변환한다
먼저 타입스크립트가 제공하는 as const 키워드를 활용해서 허용하는 확장자를 정의한 튜플 리터럴을 선언한다.
const AllowedExt = ['jpg', 'gif'] as const;
AllowedExt의 타입은 string[]
이 아니라, readonly ["jpg", "gif"]
다. as const가 요소를 추가할 수 없는 튜플로 변환시켜 주었다.
이제 AllowedExt를 이용해서 리터럴 튜플이 가진 요소들만을 가지는 유니언 타입을 선언할 수 있다.
type Ext = typeof AllowedExt[number];
Ext의 타입은 "jpg" | "gif"
가 된다. 처음에 선언한 것과 같이 원하는 타입이 만들어졌다!
그리고 이제 유효성 검사를 @IsExt 대신 @IsIn(AllowedExt) 처럼 할 수 있다.
const AllowedExt = ['jpg', 'gif'] as const;
type Ext = typeof AllowedExt[number];
import { IsIn, Validator } from 'class-validator';
class File {
@IsIn(AllowedExt)
ext: Ext;
constructor(ext: Ext) {
this.ext = ext;
}
}
const validator = new Validator();
validator.validateSync(new File('gif')); // 유효성 검사 통과
validator.validateSync(new File('bmp' as Ext)); // 수행결과는 ValidationError
'Tips > Typescript' 카테고리의 다른 글
vscode에서 편집중인 typescript 파일을 실행하도록 설정하기 (0) | 2020.06.06 |
---|