참고 : 한 입 크기로 잘라먹는 타입스크립트 / docs
// number
let num1: number = 123;
let num2: number = -123;
let num3: number = 0.123;
let num4: number = -0.123;
let num5: number = Infinity;
let num6: number = -Infinity;
let num7: number = NaN;
// string
let str1: string = "hello";
let str2: string = 'hello';
let str3: string = `hello`;
let str4: string = `hello ${num1}`;
// boolean
let bool1: boolean = true;
let bool2: boolean = false;
// null
let null1: null = null;
// undefined
let unde1: undefined = undefined;
:number
와 같이 타입을 작성하는 문법을 타입 주석(annotation) 이라 한다.
만약, 다른 타입의 변수에 null 값을 임시로 넣고 싶다면 tsconfig.json에서 "strictNullChecks:false"를 추가 해주면 된다. "strictNullChecks" 옵션은 "strict"옵션의 하위 호환 버전으로 "strict"옵션을 끄면 "strictNullChecks"도 같이 꺼진다.
let numB: 10 = 10;
let strA: "hello" = "hello";
let boolA: true = true;
// 배열
let numArr: number[] = [1, 2, 3];
let strArr: string[] = ["hello", "im", "yricog"];
let boolArr: Array<boolean> = [true, false, true]; // 제네릭 문법
// 배열 요소의 타입이 다양할 경우
let multiArr: (number | string)[] = [1, "hello"]; // 유니온 타입
// 다차원 배열의 타입 정의
let doubleArr: number[][] = [
[1, 2, 3],
[4, 5],
];
let tup1: [number, number] = [1, 2];
let tup2: [number, string, boolean] = [1, "2", true];
/**
* js로 컴파일하면 일반 배열이기 때문에 배열 메서드 사용 가능!
* 이 때 push, pop을 사용해도 에러가 나지 않는 것은
* 길이에 제한을 두지 않기 때문이다.
*/
tup1.push(1);
tup1.pop();
tup1.pop();
tup1.pop(); // 정상!
const users: [string, number][] = [
["이아무개", 1],
["김수민", 2],
["박나래", 3],
["김아라", 4],
];
let user: { // 객체 리터럴 타입
id?: number; // optional property
name: string;
} = {
id: 1,
name: "yricog",
};
user.id;
user = { name: "홍길동" }; // id는 옵셔널
let config: {
readonly apiKey: string; // readonly
} = {
apiKey: "API KEY",
};
// config.apiKey = "hacked"; 변경 불가능!
타입을 object로 지정하면 객체 안에 object만 남는다.
그래서 user.id 와 같이 속성을 지정하면 없는 속성이 된다.
위와 같이 구조를 기준으로 타입을 정의하는 것을 '구조적 타입 시스템(Property Based Type System)'이라 한다.
type User = {
id: number;
name: string;
nickname: string;
birth: string;
bio: string;
location: string;
};
let user: User = {
id: 1,
name: "jenna",
nickname: "jj",
birth: "1999.01.08",
bio: "안녕하세요",
location: "서울시",
};
type CountryCodes = {
[key: string]: string; // 인덱스 시그니처, 비어있어도 된다
Korea: number; // 꼭 필요한 값
};
let countryCodes: CountryCodes = {
UnitedState: "us", // key가 string이면 어떤걸 추가해도 ok.
UnitedKingdom: "uk",
Korea: "ko", // 없으면 에러
};
enum Role {
ADMIN = 0,
USER = 1,
GUEST = 2,
}
enum Language {
korean = "ko",
english = "en",
}
const user1 = {
name: "김이박",
role: Role.ADMIN, //0
language: Language.korean,
};
const user2 = {
name: "홍길동",
role: Role.USER, //1
};
const user3 = {
name: "아무개",
role: Role.GUEST, //2
};
let anyVar: any = 10;
// 모든 타입 할당 가능
anyVar = "hello";
anyVar = true;
anyVar = 1;
anyVar = {};
anyVar = () => {};
let num: number = 10;
num = anyVar; // ❗️ 모든 타입의 값에 할당되어질 수 있다.
let unknownVar: unknown;
// 모든 타입 할당 가능
unknownVar = "hello";
unknownVar = true;
unknownVar = 1;
unknownVar = {};
unknownVar = () => {};
let num: number = 10;
num = unknownVar; // 할당 불가❌
// 타입 정제 후 할당 가능
if (typeof unknownVar === "number") {
num = unknownVar;
}
function func1(): string {
return "hello"; // string을 리턴
}
function func2(): void {
console.log("hello"); // 그냥 출력문, 아무것도 리턴하지 않음
}
let a: void;
a = 1; // 할당 불가❌
a = "hello"; // 할당 불가❌
a = {}; // 할당 불가❌
a = undefined; // 오직 undefined만 담을 수 있다
function func3(): never {
while (true) {} // 무한 루프
}
function func4(): never {
throw new Error(); // 실행 시 프로그램 종료
}
// ❗️변수에 never 타입을 사용할 순 있지만, 아무런 값도 담을 수 없다.
let b: never;