2025년 2월 28일
특정 변수의 타입을 우리가 확실히 모를 때 사용
타입스크립트는 초기화 하는 값을 기준으로 변수의 타입을 자동 추론함
자바스크립트 변수를 쓰듯이, 아무값이나 담을 수 있게 하려면 any타입을 설정하면 됨
any 타입은 모든 타입의 값을 할당 받을 수 있고, 반대로 모든 타입의 변수에 다 any 타입의 값을 집어 넣을 수도 있음
어떤 타입의 메서드를 사용해도 됨
타입스크립트의 타입 검사를 모두 통과하는 치트키 같은 것임
따라서, any 타입은 가능한 한, 최대한 사용하지 않는 것이 좋음!!!
// any
let anyVar: any = 10;
anyVar.toUpperCase();
let num: number = 10;
num = anyVar;
any와 비슷한 타입임 (아무 타입의 값을 다 집어 넣을 수 있음)
만약 변수에 어떤 타입이 들어올지 모를때, any와 unknown 둘 중하나를 쓸 수 있음
그러나, 차이가 있음!!
unknown 타입은 모든 값을 저장할 수는 있지만, 반대는 안됨(any는 가능)
any와는 다르게 메서드를 사용 수 없고, 연산도 안됨
따라서, 우리가 변수에 저장할 값의 타입이 확실하지 않을때는 any타입보다는 조금 더 안전한 unknwon 타입을 활용하는 것이 좋음!
// unknown
let unknownVar: unknown;
unknownVar = '';
unknownVar = 1;
unknownVar = () => {};
let num: number = 10;
num = unknownVar // 오류
num.toUpperCase() // 오류
if(typeof unknownVar === 'number') {
num = unknownVar;
}
타입스크립트에서는 함수 반환값의 타입을 지정할 수도 있음
아무런 값도 반환하지 않을때 void 타입을 사용함
변수에도 void 타입을 정의할 수 있음
굳이 반환값이 없는 함수의 타입의 반환값을 정의할 때 undefined 이나 unknwon을 쓰지 않는 이유는?
// void
// void -> 공허 -> 아무것도 없다
// void -> 아무것도 없음을 의미하는 타입
function func1 (): string {
return 'hello';
}
function fun2(): void {
console.log('hello');
}
let a: void;
// a = 1; 오류
// a = 'hello'; 오류
// a = {}; 오류
a = undefined;
// a = ull; strictNullCheck = false일 경우 오류 발생하지 않음
불가능한 타입
무한 루프를 도는 함수의 반환값 타입을 어떤걸로 정의해야 할까?
아무값도 반환하지 않으므로 void를 써야할까?
위의 func2 함수를 보면, 반환하는 값 자체가 없이 정상적으로 종료된 것을 볼 수 있지만, func3는 반환할 수 없는 상태여서 애초에 정상적으로 종료가 되지 않는다. (함수가 뭔가를 반환하는 자체가 모순이고 불가능할때 never을 사용)
e.g) 오류를 던지는 함수
never도 변수의 타입을 정의하는데 사용할 수 있는데, void값과 똑같이 어떠한 값에도 오류가 발생하고, undefined에도 오류가 발생함
never 타입을 변수의 타입으로 활용하면, 그 어떠한 값도 저장할 수 없는 변수의 타입을 정의할때 사용할 수 있음
// never
// never -> 존재하지 않는
// 불가능한 타입
function func3(): never {
while (true) {}
}
function func4(): never {
throw new Error();
}
let anyVar: any;
let b: never;
// b = 1; 오류
// b = 'hello'; 오류
// b = {}; 오류
// b = anyVar; 오류
타입스크립트가 말하는 타입은 집합임
타입스크립트가 말하는 타입이란, 값들을 포함하고 있는 집합임
타입스크립트의 타입들이 서로 집합이고, 계층을 이루고 있다는 것을 알고 있으면 타입 간의 호환성을 이해할 수 있음
let num1: number = 10;
let num2: 10 = 10;
num1 = num2; // 10을 number에 넣을 수 있음
num2 = num1; // 오류 발생. number을 10에 넣을 수 없음
다운 캐스팅은 대부분의 상황에 허용되지 않고, 업 캐스팅은 모든 상황에 가능함
타입 계층의 최상단에 위치하고 있음
업 캐스팅은 모두 다 허용 -> unknown 타입은 모든 타입의 슈퍼 타입이기 때문에 모든 값을 집어 넣을 수 있음 (계층도를 보면 이해 더 쉬움!!)
그런데, unknown 타입의 값은 any를 제외한 어떤 타입의 변수에도 할당할 수 없음 -> 다운 캐스팅
e.g) number 타입의 변수에 unknown 값을 넣겠다는 것
결국, unknown 타입의 변수에는 모든 값을 넣을 수는 있지만(업 캐스팅), 반대로 unknown 타입의 값은 어떤 타입의 변수에도 들어갈 수 없음(다운 캐스팅)
/**
* Unknown 타입
*/
function unknownExam() {
let a: unknown = 1;
let b: unknown = 'hello';
let c: unknown = true;
let d: unknown = null;
let e: unknown = undefined;
let f: unknown = {};
let unknownVar: unknown;
// let num: number = unknownVar; 오류
// let str: string = unknownVar; 오류
// let bool: boolean = unknownVar; 오류
}
불가능, 모순을 의미하는 타입
nver 타입을 타입 계층도에서 보면, 가장 아래에 위치한 것을 볼 수 있음
반환할 수 있는 값의 종류가 아무 것도 없다는 뜻 = 공집합
never 타입은 모든 타입의 서브 타입이기 때문에 어떠한 타입의 변수의 값이 될 수 있음 (업 캐스팅)
반대로, never 타입의 변수에는 어떠한 타입의 값을 넣을 수 없음(다운 캐스팅)
따라서, never 타입은 어떤 값도 저장되어서는 안되는 변수에 활용할 때 좋음 (never 타입에 아무런 값을 저장할 수 없게할 때)
/**
* Never 타입
*/
function neverExam() {
function neverFunc(): never {
while (true) {}
}
let num: number = neverFunc();
let str: string = neverFunc();
let bool: boolean = neverFunc();
// let never1: never = 10; 오류
// let never2: never = 'string'; 오류
// let never3: never = true; 오류
}
반환 값이 없는 함수, 즉 return문 자체가 없는 함수의 타입을 명시하는 데 사용
undefined 타입과 never 타입의 슈퍼 타입임
/**
* Void 타입
*/
function voidExam() {
function voidFunc(): void {
console.log('hi');
return undefined;
}
let voidVar: void = undefined;
}
any 타입은 계층도 상에서는 unknown 타입의 서브 타입에 위치한 것으로 보이지만, any 타입은 타입 계층도를 완전히 무시함
any 타입은 자기한테 오는 다운 캐스팅도 되고, 자기가 다운 캐스팅하는 것도 가능 -> 치트키 타입
따라서, 타입 계층도를 완전히 무시하는 타입이라 사용하는것을 권장하지 않는다고 함
never 타입의 변수에 any 타입 값을 할당하지 못함!!!!
e.g) any 타입의 값을 never 타입의 변수로 할당 불가능 (다운 캐스팅)
/**
* Any 타입
*/
function anyExam() {
let unknownVar: unknown;
let anyVar: any;
let undefinedVar: undefined;
let neverVar: never;
anyVar = unknownVar;
undefinedVar = anyVar;
// neverVar = anyVar; 오류
}