타입을 다 기재할 필요 없이 변수에 담아 사용 가능하다.
// 아래 변수의 타입을
let value: string = "lee";
// alias해서 사용
type Name = string;
let newValue: Name = "lee";
const 변수는 값을 바꿀 수 없지만, object의 내용은 바꿀 수 있다.
그래서 그 값을 변경하지 못하도록 readonly로 만들 수 있다.
const name = "lee";
name = "kim"; // 에러
const value = { name : "lee", age : 25 };
value.name = "kim"; // 에러 안남
type Person = {
readonly name : string,
age : number
}
const newValue : Person = { name : "lee", age : 25 };
newValue.name = "kim"; // 에러
newValue.age = 33; // 에러 안남
object는 & 키워드로 type을 합칠 수 있다.
하지만 같은 이름의 속성을 합칠 경우, 오른쪽에 있는 오브젝트의 타입으로 지정되거나 never 변수가 된다.(never는 나중에..)
type a = {a: number};
type b = {a: string};
type c = a & b; // never
let temp3: c = {a:"1"}; // 에러
// 정상적으로 쓴다면
type a = {a: number};
type b = {b: string};
type c = a & b;
let temp3: c = { a : 1, b : "문자열" };
변수를 primitive type이 아니라 좀 더 명확하게 지정할 수 있고, literal type이라 부른다.
// "바나나" | "딸기" | "사과" 세 개 중에 하나만 들어갈 수 있다.
type Literal = "바나나" | "딸기" | "사과"
let value1 = "멜론"; // 에러
let value2 = "바나나"; // 에러 안남
// 함수도 가능
function func(param: "바나나" | "딸기" | "사과"): 1 | 0 {
if(typeof param === "Literal") {
return 1;
} else {
return 0;
}
}
이를 통해 에러를 좀 더 방지할 수 있으며, 스니펫이 지원되어 값 넣기가 편해지기도 한다.
literal type에서 object를 사용할 때는 애매한 상황이 발생하기도 하는데 아래와 같은 문제가 있다.
let value = {
name : "lee",
age : number
}
function func(param : "lee"): void {
console.log(param);
}
console.log(value.name) // "lee"
// 위처럼 콘솔을 찍으면 "lee"가 출력된다.
// func함수의 param의 타입도 "lee"이다.
// 이론상으로는 func(Person.name) 을 호출할 경우 정상적으로 호출되어야 한다.
func(Person.name) // 에러
에러가 발생하는 이유는, param은 "lee"라는 타입이지만 Person.name은 "lee" 라는 문자열이기 때문이다.
즉, param : "lee" 의 의미는 "lee"라는 값을 넣을 수 있다가 아니라 "lee"라는 타입을 넣을 수 있다는 의미이다.
사견으로는 말장난처럼 생각되긴 하는데, 아마도 js에 타입 개념을 넣다보니 구멍이 생길 수 밖에 없지 않을까 싶다.
어쨋든, 이러한 문제를 해결하는 방법은 두가지가 있는데
1. 변수에 타입을 명확하게 지정한다.
1-1. assertion의 as 로 타입을 속인다.
2. as const 키워드를 이용해 const화 시킨다.
// 1. 타입을 명확히
let value : { name : "lee", age : number } = {
name : "lee",
age : 14
}
function func(param : "lee"): void {
console.log(param);
}
func(value.name)
// 혹은 assertion의 as로 사용
func(value.name as "lee");
2. as const를 사용하면 아래처럼 변수의 선언문이 내부적으로 변경되어 정상적으로 사용할 수 있다.
as const를 붙이기 전에는 name의 타입은 string이 었지만,
as const를 붙임으로 인해 readonly 속성이 붙고 name의 value였던 "lee" 가 타입이 된다.
literal type을 함수에도 사용가능하지만 return 값은 엄격하게 보고 parameter는 그렇지 못한 부분이 있다.
아래의 temp5~7모두 정상적으로 실행이 가능한데, js로 변환된걸 보면 왜 정상인지 알 수가 있다.
하지만 그럼에도 temp5~7의 값에 들어있는 함수에 a라는 parameter가 없는데도 에러 체크 하지 않는 부분은 좀 아쉽다.
type FuncType = (a: string) => number;
let temp5 : FuncType = () => {
console.log("temp5");
return 10;
};
let temp6 : FuncType = function () {
console.log("temp6");
return 10;
}
let temp7 : FuncType = function func5() {
console.log("temp7");
return 10;
}
temp5("lee");
temp6("lee");
temp7("lee");
위 ts 파일이 js로 컴파일 되면
let temp5 = () => {
console.log("temp5");
return 10;
};
let temp6 = function () {
console.log("temp6");
return 10;
};
let temp7 = function func5() {
console.log("temp7");
return 10;
};
temp5("lee");
temp6("lee");
temp7("lee");
댓글