변수 선언할 때 타입을 명시한다. 그러나 아래와 같이 기본적인 경우는 굳이 모든 변수에 타입 명시 안해도 된다.
let 이름: string = "kim";
let 나이: number = 20;
let 불리언: boolean = True;
let 널: null = null;
let 언디파인: undefined = undefined;
let 회원들: string[] = ["kim", "park"];
let 회원정보: { name: string; age: number } = { name: "kim", age: 20 };
type 여러 개 중에 선택 가능하게 해주는 기능이다.
let 회원: number | string = 123;
회원 = "abc";
let 회원들: (number | string)[] = [1, 2, '3'];
let 오브젝트: { a: string | number } = { a: "123" };
주의할 점: 수학 연산은 number 타입이 확실할 때만 가능하다
let 나이2: string | number;
console.log(나이2 + 1); // 에러
나이2 = 20;
console.log(나이2 + 1) // 정상 출력
아무 타입이든 할당 가능하게 해준다.
let 이름3: any;
이름3 = 123;
이름3 = true;
이름3 = [];
그런데 any를 쓰면 typeScript 쓰는 이유가 없어진다. 따라서 일반 JS 변수로 쓰고 싶을때만 사용한다. 즉, 타입 쉴드 해제 문법이다.
any 보다 조금 더 안전하다. 다른 타입 변수에 할당 방지해준다.
let 이름4: unknown;
이름4 = 123;
이름4 = {};
let 변수: string = 이름4 // 에러
단, 수학 연산 사용 시 에러를 발생시킨다.
let 이름5: unknown;
이름5 = 123;
console.log(이름5 - 1); // 에러
Union type, unknown type에서 수학 연산을 사용하고 싶다면 narrowing 또는 assertion을 이용해서 엄격하게 코드를 짜야한다.
function 함수(x: number): number {
return x * 2;
}
function 함수2(x: number): void {
console.log(x);
}
function 함수3(x?: number): void {}
// 위랑 같은 코드
function 함수4(x: number | undefined): void {}
function 함수(...x: string[]): void {
x.forEach((a) => {
console.log(a);
})
}
함수('hi');
함수('hello', 'world', '!');
...(점 세 개) 문법
- 일반 패러미터와 rest 패러미터를 같이 쓸 때, rest 패러미터가 뒤에 와야 한다.
function 함수(x: number, ...y: string[]): void { }
- ...(점 세 개)를 이용하는 문법은 rest parameter 외에 spread operator로 사용된다. spread operator는 array나 object 옆에 쓰일 때 괄호 없애준다.
let arr = [1, 2, 3]; let arr2 = [4, 5]; let arr3 = [...arr, ...arr2]; console.log(arr3); // 출력: 1, 2, 3, 4, 5
함수 패러미터로 Destructuring을 사용할 땐 다음과 같이 사용한다.
// Object 패러미터
function 함수({ x, y }: { x: number; y: number }): void {
console.log(x, y);
}
함수({ x: 1, y: 2 });
// Array 패러미터
function 함수2([num, str, bool]: (number | string | boolean)[]): void {
console.log(num, str, bool);
}
함수2([40, "wine", false]);
Destructuring: 아래와 같이 mapping 시켜주는 것
let [변수1, 변수2] = ["hi", 100]; console.log(변수1); // hi console.log(변수2); // 100
let { student: student, age: age } = { student: true, age: 20 };
단, 자바스크립트 신문법에 의하여 위와 같이 변수 이름이 같다면 생략 가능하다.
let { student, age } = { student: true, age: 20 };
function 함수(): never {
// never 타입을 리턴하는 경우
// 1. 에러 발생
throw new Error();
// 2. 무한 루프
while (true) {}
}
function 함수(x: string) {
if (typeof x == "string") {
console.log(x);
} else {
// 이 부분 x는 never 타입
// ( 이 조건이 걸리는건 있을 수 없기 때문)
console.log(x);
}
}
오브젝트에서 readonly를 활용하여 속성 값은 변경하지 못하게 설정 가능하다.
// const가 있더라도 오브젝트 내의 값은 수정 가능
const 출생지역 = { region: "seoul" };
출생지역.region = "busan";
// readonly를 이용하면 오브젝트 내의 속성도 lock 가능
const person: { readonly name: string; age: number } = { name: "abc", age: 20 };
person.name = "def"; // 에러
person.age = 23; // readonly가 없으므로 변경 가능
const는 변수의 '=' 할당만 막기 때문에 해당 오브젝트 내의 속성은 변경이 가능하다. 따라서 속성 변경도 막고 싶다면 readonly를 이용하면 된다.
// object에 타입 작성할 때, 타입이 확실하지 않을 때에는 물음표 붙이면 된다.
let 타입불확실: { name?: string } = { name: "kim" };