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.
숫자 혹은 문자열 값(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 를 설정하면 값을 반환하지 않겠다는 의미이다. 반환값이 없는 함수는 실제로 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 를 사용할 경우, 항상 오류를 출력하거나 리턴 값을 절대로 내보내지 않음을 의미한다. 이는 무한 루프에 빠지는 것과 같다.
만약 무한 루프에 빠지지 않거나, 리턴 값을 내보내는 경우 에러가 발생한다.
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