let isDone: boolean = false;
isDone = true;
console.log(typeof isDone); //boolean
let isOk:Boolean = true;
let isNotOk:boolean = new Boolean(true); //boolean은 기본개체이지만 Bollean은 래퍼개체로 오류가 발생한다.
모든 숫자는 부동 소수점 값이다.
let decimal:number = 6;
let hex:number = 0xf00d; //16진수
let binary:number = 0b1010; //2진수
let octal:number = 0o744; //8진수
let notANumber : number = NaN;
let underscoreNum :number = 1_000_000;
let myName: string = "Mark";
myName = "Anna";
//Template String 행에 걸쳐있거나 표현식을 넣을 수 있는 문자열 ` backquote 기호와 ${} 를 통해 사용할 수 있다.
let fullName: string = "Mark Lee";
let age: number = 30;
let sentence: string = `Hello, my name is ${fullName}.
i'll be ${age + 1} years old next month`;
console.log(sentence); // Hello, my name is Mark Lee. i'll be 31 years old next month
new Symbol
로 사용할 수 없다. 함수로 사용해서 타입을 만들어낼 수 있다.
고유하고 수정불가능한 값으로 만들어줘 주로 접근을 제어하는데 쓰는 경우가 많다.
const sym = Symbol();
const obj = {
[sym] : "value",
};
// obj["sym"] 접근이 불가능 하다.
obj[sym]
tsconfig.json
에서 --strictNullChecks
를 사용하면 null과 undefined는 void나 자기자신에게만 할당할 수 있다.
null
타입은 null값만 가질수 있으며 런타임에서의 타입은 object이다.
undefined
런타임에서의 타입은 undefined이다.
let MyName: string = null; //Error
let u:undefined = null; //Error
let v:void = undefined;
let union: string | null = null;
union = 'mark';
primitive type이 아닌 것을 나타내고 싶을 때 사용하는 타입이다.
(non-primitive type : number,string,boolean,bigint,symbol,null or undefined)
자바스트립트에서 array는 객체이다.
let list1:(number | string)[] = [1,2,3,"4"];
let list2:Array<number> = [1,2,3]; //자주 사용은 안한다.
순서와type,길이가 맞아야한다.
let x:[string,number];
x = ["hello",10];
x = [10 , "mark"]; //error
x[2] = "world"; //error
const person:[string, number]= ['mark', 20];
const [first, second] = person;
어떤 타입이어도 상관없는 타입
컴파일타임에 타입 체크가 정상적으로 이뤄지지 않아 최대한 사용하지 않는게 좋다.
function returnAny(message: any): any {
console.log(message);
}
const any1 = returnAny("리턴은 아무거나");
any1.toString();
let looselyTyped: any = {};
const d = looselyTyped.a.b.c.d;
function leakingAny(obj: any) {
const a = obj.num; //a = any
const b = a + 1; //b = any
return b;
}
const c = leakingAny({ num: 0 }); //c = any
c.indexof("0")
모르는 타입의 변수를 지정할때 사용한다.
any와 같이 아무거나 할당할 수 있다.
컴파일러가 타입을 추론할 수 있게끔 타입의 유형을 좁히거나, 타입을 지정해주지 않으면 다른 곳에 할당 할 수 없고, 사용할 수 없다.
unknown타입을 사용하면 runtime error를 줄일수 있다.
(사용전에 데이터의 일부 유형의 검사를 수행해야하는 API에 사용한다.)
declare const maybe:unknown;
const aNumber:number = maybe;
if(maybe === true){
const aBollean:boolean = maybe; //true
// const aString:string = maybe; error
}
if(typeof maybe === 'string'){
const aString:string = maybe // string
}
모든타입에 subtype 이며, 모든 타입에 할당 할 수 있다.
never에는 그 어떤 것도 할당할 수 없다.(any도 불가능)
잘못된 타입을 넣는 실수를 막고자 사용한다.
function error(message: string): never {
throw new Error(message);
}
function fail() {
return error("failed"); //never
}
function infiniteLoop() :never{
while(true){
}
}
let a:string = 'hello';
if(typeof a !== "string") {
//a에는 아무것도 할당할 수 없다.
}
declare const b:string|number;
if (typeof b !== "string") {
b //number
}
type Indexable<T> = T extends string ? T & {[index:string]:any} : never;
함수의 반환타입으로 사용된다.
function returnVoid (message:string):void{
console.log(message);
return; // return undefined
}
const r = returnVoid('리턴이 없다.'); //r = void 타입
key값들을 Union형태로 받을 수 있음.
interface User {
id: number;
name: string;
age: number;
gender: "m" | "f";
}
type UserKey = keyof User; // "id" | "name" | "age" | "gender"
// keyof를 통해 User interface의 key값들을 Union 형태로 받음
const uk1:UserKey = ""; // [에러 발생]
const uk2:UserKey = "id"; // [에러 해결] User interface의 key값 중 하나 입력입력하세요
모든 프로퍼티 → 옵셔널로 전환 (즉, 일부만 사용 가능)
없는 프로퍼티 사용 시 에러 발생
interface User {
id: number;
name: string;
age: number;
gender: "m" | "f";
}
// [에러 발생] 이유: age, gender 無
let admin1: User = { // 👈
id: 1,
name: "Bob",
};
// [에러 無]
let admin2: Partial<User> = { // 👈
id: 1,
name: "Bob",
};
/*
- 아래와 같음:
interface User {
id?: number;
name?: string;
age?: number;
gender?: "m" | "f";
} */
모든 프로퍼티 -> 필수로 전환
interface User {
id: number;
name: string;
age?: number; // 👈 옵션
}
let admin: Required<User> = { // 👈
id: 1,
name: "Bob",
age: 30, // 👈 Required<T>를 넣어서 age도 필수. 안 넣으면 에러 발생
}
모든 프로퍼티 → 읽기 전용으로 전환
interface User {
id: number;
name: string;
age?: number;
}
// [기존] 처음 할당 후, 수정 가능
let admin1: User = {
id: 1,
name: "Bob",
};
admin1.id = 4;
// [적용] 처음 할당 후, 수정 불가
let admin2: Readonly<User> = {
id: 1,
name: "Bob",
};
admin2.id = 4; // ⛔ [id 에러 발생]
K: key
T: type
[점수 객체 제작] 1~4학년의 점수 입력
interface Score {
"1": "A" | "B" | "C" | "D";
"2": "A" | "B" | "C" | "D";
"3": "A" | "B" | "C" | "D";
"4": "A" | "B" | "C" | "D";
}
const score: Score = {
1: "A",
2: "B",
3: "C",
4: "D",
}
const score: Record<'1'| '2' | '3' | '4', 'A' | 'B' | 'C' | 'D'> = {
1: "A",
2: "C",
3: "B",
4: "D",
}
type Grade = '1' | '2' | '3' | '4' ;
type Score = 'A' | 'B' | 'C' | 'D' | 'F' ;
const score: Record<Grade, Score> = {
1: "A",
2: "C",
3: "B",
4: "D",
}
적절한 값이 입력되었는지 체크하는 함수 제작
interface User {
id: number;
name: string;
age: number;
}
function isValid(user: User) {
const result: Record<keyof User, boolean> = {
id: user.id > 0,
name: user.name !== '',
age: user.age > 0
}
return result
}
/*
[함수 기능]
user를 받아서 결과 객체(result) 제작 -> 조건 체크 -> 결과 리턴
[result 타입]
keyof User: result의 key는 User의 key
boolean: type은 모두 boolean */
T타입에서 K프로퍼티만 골라서(Pick) 사용.
Omit<T, K> 반대
interface User {
id: number;
name: string;
age: number;
gender: "M" | "W"
}
const admin: Pick<User, "id" | "name"> = { // 👈 User에서 "id"와 "name"만 사용
id: 0,
name: "Bob"
}
T타입에서 K프로퍼티만 생략(Omit)
Pick<T, K> 반대
interface User {
id: number;
name: string;
age: number;
gender: "M" | "W"
}
const admin: Omit<User, "age" | "gender"> = { // 👈 User에서 age & gender 제외한 나머지 사용
id: 0,
name: "Bob"
}
T1 타입들 중 T2타입과 겹치는 타입 제외
Omit과 차이
Omit: 프로퍼티들 제거.
Exclude: Type으로 제거.
// ex 1)
type T1 = string | number;
type T2 = Exclude<T1, number> // string. (T1에서 number를 제외)
// ex 2)
type T3 = string | number | boolean;
type T4 = Exclude<T3, number | string> // boolean
null & undefined 제외한 타입 생성
type T1 = string | null | undefined | void;
type T2 = NonNullable<T1> // string | void