Tuple, Enum, Void, Never

Hyun·2022년 6월 30일
0

typescript

목록 보기
3/3

Tuple

tuple 타입은 배열과 매우 유사하다. 차이점은 정해진 타입의 고정된 길이(length) 배열이라는 점이다.

let tuple: [string, number];
tuple = ['a', 1];
tuple = ['a', 1, 2]; // 고정된 길이, Error - TS2322
tuple = [1, 'a']; // 고정된 타입, Error - TS2322

데이터를 개별 변수로 지정하지 않고, 단일 tuple 타입으로 지정해 사용할 수도 있다.

let userId: number = 1234;
let userName: string = 'HEROPY';
let isValid: boolean = true;

// Tuple
let user: [number, string, boolean] = [1234, 'HEROPY', true];
console.log(user[0]); // 1234
console.log(user[1]); // 'HEROPY'
console.log(user[2]); // true

근데 사실 유저 정보를 정해진 타입, 고정된 길이만 보고 tuple 을 사용하는 것보다, 아래처럼 interface 로 유저 타입을 미리 정해놓고, 유저 정보를 생성할때마다 해당 interface 를 참조하는게 더 좋을 것 같다.

interface IUser {
    userId: number,
    userName:string,
    isValid: boolean,
}
let user: IUser = {
    userId: 1234,
    userName: "HEROPY",
    isValid: true,
}

tuple 타입의 2차원 배열을 사용할 수도 있다.

let users: [number, string, boolean][];
// Or
// let users: Array<[number, string, boolean]>;

users = [[1, 'Neo', true], [2, 'Evan', false], [3, 'Lewis', true]];

값으로 타입을 대신할 수도 있다. (타입 고정 -> 값 고정)

let tuple: [1, number]; // 1 은 변경 불가
tuple = [1, 2];
tuple = [1, 3];
tuple = [2, 3]; // 변경 불가 Error - TS2322: Type '2' is not assignable to type '1'.11

tuple 은 정해진 타입의 고정된 길이 배열을 표현하지만, 이는 할당(Assgin) 에만 국한된다. .push().splice() 등 값을 넣는 행위는 막을 수 없다. 다만 정해진 타입은 지켜야 한다.

let tuple: [string, number];
tuple = ['a', 1];
tuple = ['b', 2];
tuple.push(3); // 값을 넣는 것은 막을 수 없다.
console.log(tuple); // ['b', 2, 3];
tuple.push(true); // 그래도 타입은 지켜야한다. Error - TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'.

배열처럼 readonly 키워드를 이용해 읽기 전용 튜플을 생성할 수도 있다.

let a: readonly [string, number] = ['Hello', 123];
a[0] = 'World'; // 읽기 전용, 임의의 값 변경 불가 Error - TS2540: Cannot assign to '0' because it is a read-only property.

Enum

숫자 혹은 문자열 값(value) 집합에 이름(Member => key) 을 부여할 수 있는 타입, 값의 종류가 일정한 범위로 정해져 있는 경우 유용하다.

기본적으로 0 부터 시작하며 값은 1 씩 증가한다.

enum Week {
  Sun,// = 0
  Mon,// = 1
  Tue,// = 2
  Wed,// = 3
  Thu,// = 4
  Fri,// = 5
  Sat// = 6
}
console.log(Week.Mon); // 1
console.log(Week.Tue); // 2

수동으로 값을 변경할 수 있으며, 변경한 부분부터 다시 1 씩 증가한다.

enum Week {
  Sun,// = 0
  Mon,// = 1
  Tue,// = 23
  Wed,// = 24
  Thu,// = 25
  Fri,// = 26
  Sat// = 27
}
console.log(Week.Mon); // 1
console.log(Week.Tue); // 23

Enum 타입은 역방향 매핑(Reverse Mapping) 을 지원한다. 열거된 멤버(key) 로 값(value) 에, 값(value) 으로 멤버(key) 에 접근할 수 있다는 것을 의미한다. 즉, key <-> value 둘다 역할 바꿔서 사용할 수 있다(애초에 세팅도 그렇게 되어있다).

// 숫자값 열거 상태
enum Week {
    Sun,// = 0
    Mon,// = 1
    Tue = 23,// = 23
    Wed,// = 24
    Thu,// = 25
    Fri,// = 26
    Sat// = 27
  }
console.log(Week);
/*
 {
    '0': 'Sun',
    '1': 'Mon',
    '23': 'Tue',
    '24': 'Wed',
    '25': 'Thu',
    '26': 'Fri',
    '27': 'Sat',
    Sun: 0,
    Mon: 1,
    Tue: 23,
    Wed: 24,
    Thu: 25,
    Fri: 26,
    Sat: 27
  }
*/ 
console.log(Week.Sun); // 0
console.log(Week['Sun']); // 0
console.log(Week[23]); // 'Tue', 역방향 매핑 가능

Enum 은 숫자 값 열거뿐만 아니라, 문자열 값으로도 초기화 할 수 있다. 이 경우 역방향 매핑(Reverse Mapping) 을 지원하지 않으며 개별적으로 초기화해야 한다.

//문자 값 열거 상태
enum Color {
    Red = 'red',
    Green = 'green',
    Blue = 'blue'
  }
  console.log(Color.Red); // red
  console.log(Color['Green']); // green
  console.log(Color['red']);// 에러 발생, 역방향 매핑 불가능

Void

일반적으로 값을 반환하지 않는 함수에서 사용한다. 반환 타입으로 void 를 설정하면 값을 반환하지 않겠다는 의미이다. 반환값이 없는 함수는 실제로 undefined 를 반환하는데, 이 경우에 반환값의 타입을 undefined 로 지정해주는 void 타입을 사용한다. " 반환값이 void 타입 => 반환값이 undefined "

function hello(msg: string): void {// 반환 값 타입 undefined 로 설정
  console.log(`Hello ${msg}`);
}
console.log(hello("hyun"));// 반환 값 없으므로 undefined 출력

반환 타입으로 void 타입을 설정한 후 undefined 가 아닌 값을 반환하려 하면 에러가 발생한다.

반환타입을 void 로 설정하고 undefined 를 return 했을 때, 정상적으로 작동하는 것을 볼 수 있다. " 반환값이 void 타입 => 반환값이 undefined "

Never

never 은 일반적으로 함수의 리턴 타입으로 사용된다. 함수의 리턴 타입으로 never 를 사용할 경우, 항상 오류를 출력하거나 리턴 값을 절대로 내보내지 않음을 의미한다. 이는 무한 루프에 빠지는 것과 같다.

만약 무한 루프에 빠지지 않거나, 리턴 값을 내보내는 경우 에러가 발생한다.

function throwError(msg: string): never{
    console.log("??");//  error TS2534: A function returning 'never' cannot have a reachable end point.
}
function throwError(msg: string): never{
     return "??" // error TS2322: 'string' 형식은 'never' 형식에 할당할 수 없다.
}

따라서 오류를 출력하거나 무한 루프에 빠지게 하는 코드를 사용해야 한다.

// 항상 오류 발생
function invalid(message:string): never {
  throw new Error(message);
}

// 무한 루프
function infiniteAnimate(): never {
  while ( true ) { infiniteAnimate(); }
}

never 타입을 지정한 변수에 never 가 아닌 타입은 할당할 수 없다.

let never_type:never;

// 오류 발생: 숫자 값을 never 타입 변수에 할당할 수 없다.
never_type = 99;

// 함수의 반환 값이 never 타입 이기 때문에 오류가 발생하지 않는다.
never_type = (function():never { throw new Error('ERROR') })();

[출처 및 참고자료]

yamoo9.gitbook.io/typescript/types/never
heropy.blog/2020/01/27/typescript

profile
better than yesterday

0개의 댓글