이 글은 아래 강의를 바탕으로 정리한 글입니다. 🤗
https://inf.run/UGoRu열거형 타입은 JS에는 존재하지 않고 오직 TS에서만 사용할 수 있는 특수한 타입이며, 여러가지 값들에 각각 이름을 부여해 열거해두고 사용하는 타입입니다.
// 숫자형 enum 타입
enum Role {
ADMIN = 1,
USER = 2,
GUEST = 3,
}3개의 멤버(ADMIN, USER, GUEST)를 나열한 열거형 타입을 하나 만들고 위와 같이 각 멤버에는 숫자를 할당할 수 있습니다.
그리고 다음과 같이 enum의 멤버들을 값으로도 활용할 수 있습니다.
const user1 = {
name: "john",
role: Role.ADMIN,
};
const user2 = {
name: "jane",
role: Role.USER,
};
const user3 = {
name: "doe",
role: Role.GUEST,
};
console.log(user1);
console.log(user2);
console.log(user3);
// { name: 'john', role: 1 }
// { name: 'jane', role: 2 }
// { name: 'doe', role: 3 }enum의 멤버에는 숫자 말고도 문자열 값도 할당할 수 있습니다.
따라서 만약 다음과 같이 국가별 언어를 열거하는 enum이 필요하다면 각 멤버에 문자열 값을 할당하면 됩니다.
// 문자형 enum 타입
enum Language {
KOREAN = "ko",
ENGLISH = "en",
}const user4 = {
name: "john",
language: Language.KOREAN,
};
const user5 = {
name: "jane",
language: Language.ENGLISH,
};
console.log(user4);
console.log(user5);
// { name: 'john', language: 'ko' }
// { name: 'jane', language: 'en' }⭐ Enum은 컴파일 결과 객체가 됩니다.
enum은 컴파일 될 때, 다른 타입들처럼 사라지지 않고 JS 객체로 변환됩니다.
var Role;
(function (Role) {
Role[Role["ADMIN"] = 0] = "ADMIN";
Role[Role["USER"] = 1] = "USER";
Role[Role["GUEST"] = 2] = "GUEST";
})(Role || (Role = {}));
var Language;
(function (Language) {
Language["korean"] = "ko";
Language["english"] = "en";
Language["japanese"] = "jp";
})(Language || (Language = {}));
const user1 = {⚠️ any 타입은 TS에서만 제공되는 특별한 타입으로, 타입 검사를 받지 않는 특수한 치트키 타입이며, 특정 변수의 타입을 확실히 모를 때 사용하지만 어떠한 타입 검사도 받지 않기 때문에 아무 타입의 값이나 범용적으로 담아 사용할 수 있고 또, 다양한 타입의 메서드도 마음대로 호출해서 사용해도 문제가 되지 않기 때문에
any는 최대한 사용하지 않는 것이 바람직합니다.
let anyVar: any = 10;
anyVar = "hello";
anyVar = true;
anyVar = { name: "John" };
anyVar = [1, 2, 3];
anyVar = () => {
console.log("hello");
};
anyVar = new Date();
anyVar = new Error("error");
anyVar = new Promise((resolve, reject) => {
resolve("hello");
});
anyVar = new Array<number>(1, 2, 3);
anyVar = new Map<string, number>([["key", 1]]);
anyVar = new Set<number>([1, 2, 3]);
anyVar = new WeakMap<object, number>([[{ name: "John" }, 1]]);
anyVar = new WeakSet<object>([{ name: "John" }]);
let num: number = anyVar;unknown 타입은 any 타입과 비슷하지만 보다 안전한 타입입니다.
unknown 타입은 any 타입과 마찬가지로 어떠한 값이든 할당 가능하지만 타입 추론은 불가능합니다.
💡 즉, unknown 타입은 변수의 타입으로 정의되면 모든 값을 할당받을 수 있게 되지만, 반대로 unknown 타입의 값은 그 어떤 타입의 변수에도 할당할 수 없고 모든 연산에 참가할 수 없게 됩니다.
만약 unknown 타입의 값을 number 타입의 값처럼 취급하고 곱셈 연산을 수행하게 하고 싶다면 조건문을 이용해 값이 number 타입의 값임을 보장해주어야 합니다.
let unknownVar: unknown;
unknownVar = 10;
unknownVar = "hello";
unknownVar = true;
unknownVar = { name: "John" };
unknownVar = [1, 2, 3];
unknownVar = () => {
console.log("hello");
};
unknownVar = new Date();
unknownVar = new Error("error");
unknownVar = new Promise((resolve, reject) => {
resolve("hello");
});
// num = unknownVar; // 오류 발생void 타입은 아무것도 없음을 의미하는 타입입니다.
보통 아래와 같이 아무런 값도 반환하지 않는 함수의 반환값 타입을 정의할 때 많이 사용됩니다.
function func1(): string {
return "hello";
}
function func2(): void {
console.log("hello");
}void 대신 undefined나 null을 사용해서 아무것도 반환하지 않는 함수의 반환값 타입을 정의하면 안될까 싶지만 그렇게 하게 되면 에러가 발생할거고 다음과 같이 진짜 undefined나 null을 리턴해주어야 합니다.
function func3(): undefined {
return undefined;
}
function func4(): null {
return null;
}📌 또한, 변수에 void 타입을 지정할 수도 있으나 void 타입의 변수에는 undefined 이외의 다른 타입의 값은 담을 수 없습니다.
let a: void;
// void 타입은 어떠한 값(undefined 외)도 할당할 수 없음 (컴파일 오류 발생)
// a = 1;
// a = "hello";
// a = true;
// a = { name: "John" };
// a = [1, 2, 3];
// a = () => {
// console.log("hello");
// };
// a = new Date();
// a = new Error("error");
// a = new Promise((resolve, reject) => {
// resolve("hello");
// });never 타입은 불가능을 의미하는 타입입니다.
보통 다음과 같이 어떠한 값도 반환할 수 없는 (정상적으로 종료되지 않는) 함수의 반환값 타입을 정의할 때, 사용됩니다.
function func5(): never {
while (true) {}
}
function func6(): never {
throw new Error();
}🚫 또한, 변수 타입을 never로 정의하면 any를 포함해 그 어떠한 타입의 값도 할당할 수 없게 됩니다.
// never 타입은 어떠한 값도 할당할 수 없음 (undefined, null 포함)
let b: never;
// b = undefined;
// b = null;
// b = 1;
// b = "hello";
// b = true;
// b = { name: "John" };
// b = [1, 2, 3];
// b = () => {
// console.log("hello");
// };
// b = new Date();
// b = new Error("error");
// b = new Promise((resolve, reject) => {
// resolve("hello");
// });