- 컴파일러의 역할
- 실제 프로젝트에서 타입 검사를 자동으로 안해줌
=> 직접 코드를 입력해서 타입 검사를 해야함.
=> tsc --noEmit (단순 타입 검사)
=> vscode나 웹스톰이 반드시 필요
- ts.config 파일
- strict, esModuleInterop은 항상 "true"로 해놓는 것이 좋다.
- strict: "true"를 하지 않으면 타입스크립트 쓰는 의미가 줄어듬 !
- forceConsistentCasingInFileNames: "true"
- 파일을 불러올 때, 윈도우의 경우 대소문자 구별을 잘 안함. 반면, 리눅스나 맥에서는 대소문자 구별을 안하면 파일을 못 찾음. 그래서 이런 경우에서 발생하는 실수를 방지하기 위해 대소문자 구분을 확실히 해서 파일을 불러올 수 있도록 하는 옵션
- skipLibCheck: "true"
- 라이브러리 체킹을 건너띄라는 것.
- 프로젝트를 진행하다보면 여러 라이브러리를 설치해서 사용하게 되는데, 각 패키지의 타입을 정리해놓은 d.ts 라는 파일이 있다. 그런데, 이 수 많은 파일들을 모두 체크하려면 컴파일러가 느려지기 때문에, 실제로 쓰는 타입만 검사하도록 하는 옵션.
- 타입스크립트
자바스크립트의 변수, 매개변수, 리턴 값에 타입을 붙이는 것.
- 타입 추론 적극 활용하기
- 타입은 최대한 좁게 적용하기
- 타입 선언
- interface, type, Array<>, 그리고 변수에 바로 선언해주기
function Add(x:number, y:number): number
function Add(x, y) {
return x + y
}
- 주의
- 빈 배열을 조심하기 !
빈 배열을 선언한 경우, 타입이 never가 될 수 있는데, 이렇게 되면 어떠한 타입도 올 수가 없다. const arr = []
arr[0]
=> 빈 배열을 주는 경우 타입을 미리 지정해주자
- Enum
변수들을 하나의 그룹으로 묶고 싶을 때 주로 사용
const enum Edirection {
Up,
Down,
Left,
Right,
}
const a = Edirection.Up;
const b = Edirection.Down;
const c = Edirection.Right;
- as const
타입스크립트가 타입 추론을 엉뚱하게 하면 직접 제대로 선언해줘야함
지정해준 값을 그대로 사용하겠다 하는 경우 'as const'를 쓸 수 있음.
const Edirection = {
Up = 1,
Down = 2,
Left = 3,
Right = 4,
}
const Edirection = {
Up = 1,
Down = 2,
Left = 3,
Right = 4,
} as const;
const obj = { a: 12, b: "world", c: true };
type key = keyof typeof obj;
const obj = { a: 12, b: "world", c: true } as const;
type key = (typeof obj)[keyof typeof obj];
- type vs interface
간단한건 type, 객체지향을 하고 싶을 땐 interface
type Animal = { breath: true };
type A = Animal & { breed: true };
type H = A & { think: true };
interface B extends A {
breed: true;
}
const b: B = { breath: true, breed: true };
function add(x: string | number, y: string | number): string | number {
return x + y;
}
type A = { hello: "world" } | { type: "script" };
const a: A = { hello: "world" };
- intersection
모든 속성이 다 있어야 한다.
type A = { hello: "world" } & { type: "script" };
const a: A = { hello: "world", type: "script" };
- 타입을 집합으로 생각하자 (좁은 타입, 넓은 타입)
좁은 타입 - 더 구체적인 타입
type A = { name: string };
type B = { age: number };
type AB = A | B;
type C = A & B;
const ab: AB = { name: "hello" };
const c: C = { name: "hello", age: 22, married: false };
const obj = { name: "hello", age: 22, married: false };
const d: C = obj;
- 잉여 속성 검사
타입스크립트에서는 객체 리터럴을 바로 대입할 때는 잉여 속성 검사라는 추가 기능이 들어간다.
- void
리턴 값을 넣으면 안됨. 리턴값 없음
매개변수와 메서드를 void로 선언해주고 리턴값을 실제 어떠한 값으로 주는건 가능
- 매개변수와 메서드의 void 의미 : 리턴 값을 사용하지 않겠다, 리턴 값이 뭐든 상관 안함
- function a():void 의미: 리턴값이 없다.
function a(): void {
return undefined;
}
a();
function a(callback: () => void): void {
return;
}
a(() => {
return "3";
});
interface Human {
}
const human: Human = {
talk() {
return "abd";
},
};
- unknown vs any
- any : 타입스크립트가 타입 체킹을 포기한다.
- unknown : 이후에 타입을 직접 정해줘야함.
interface A {
talk: () => void;
}
const a: A = {
talk() {
return 3;
},
};
const b: unknown = a.talk();
(b as A).talk();
try {
} catch (error) {
(error as Error).message
}
- 타입 가드 (타입 좁히기 기법)
원시값일 때는 typeof, 배열일 때는 Array.isArray()
function numOrStr(a: number | string) {
a.toFixed(1);
(a as number).toFixed(1);
if (typeof a === "string") {
a.split(",");
}
if (typeof a === "number") {
a.toFixed(3);
}
}
numOrStr("123");
numOrStr(3);
function numOrNumArray(a: number | number[]) {
if (Array.isArray(a)) {
a.concat(4);
} else {
a.toFixed(5);
}
}
numOrNumArray([1, 2, 3]);
numOrNumArray(3);
class A {
aaa();
}
class B {
bbb();
}
function aOrB(param: A | B) {
if (param instanceof A) {
param.aaa();
}
if (param instanceof B) {
param.bbb();
}
}
aOrB(new A());
aOrB(new B());
type B = { type: "b"; bbb: string };
type C = { type: "c"; ccc: string };
type D = { type: "d"; ddd: string };
type A = B | C | D;
function typeCheck(a: A) {
if (a.type === "b") {
a.bbb;
} else if (a.type === "c") {
a.ccc;
} else {
a.ddd;
}
}
function typeCheck2(a: A) {
if ("bbb" in a) {
a.type;
} else if ("ccc" in a) {
a.type;
} else {
a.type;
}
}
- 커스텀 타입 가드
타입을 판별을 직접 만들고, 타입을 구분해주는 커스텀 함수를 직접 만들 수 있다.
interface Cat {
meow: number;
}
interface Dog {
bow: number;
}
function carOrDog(a: Cat | Dog): a is Dog {
if ((a as Cat).meow) {
return false;
}
return true;
}
function pet(a: Cat | Dog) {
if (carOrDog(a)) {
console.log(a.bow);
}
if ("meow" in a) {
console.log(a.meow);
}
}