NestJS
[TypeScript] 타입스크립트 기초
개발조하
2023. 11. 5. 22:29
01. 기본 지식
tsc
: 타입스크립트를 자바스크립트로 변환해주는 컴파일러이자, 타입을 검사해주는 역할 또한 진행해준다.- 이는
tsconfig.json
파일로 옵션을 넣을 수 있다. - 코드를 변환해주는 역할과 타입을 검사하는 역할이 별개이다.
- 즉 타입 검사가 오류가 나더라도 코드 변환은 정상적으로 이루어진다.
tsc --noEmit
: 타입 검사만 확인하는 명령어
- 이는
02. tsc 사용하기
nodejs 에서 typescript 를 사용하기 위해서는 다음과 같은 명령어가 필요하다.
$ npm init# package.json 생성 $ sudo npm i typescript# typescript install $ sudo npx tsc --init# tsconfig.json 생성
- 여기서
tsc
명령어를 사용하기 위해서는 앞에npx
가 필요하다. (ex. npx tsc -h
)
- 여기서
tsconfig.json
파일에서 주의 깊게 봐야될 옵션esModuleInterop
strict
forceConsistentCasingInFileNames
: 입포트 하는 파일 이름의 대소문자 구별하도록 하는 옵션skipLibCheck
: 실제로 사용하고 있는 파일의₩ 타입만 확인하도록 하는 옵션
03. TypeScript 실습 (내가 몰랐던 부분들만 정리)
03-01. 타입 자체를 정의할 수 있음. (type
, interface
, function
)
type
을 통해서 Add 라는 새로운 자료형을 정의할 수 있다.예제
//* type 을 통해서 Add 라는 새로운 자료형을 정의할 수 있다.type Add = (x: number, y: number) => number; const add: Add = (x, y) => x + y; console.log(add(3, 4));
interface
로도 타입을 정의하여 사용할 수 있다. (이 방법은 흔하지는 않다.)interface Add { (x: number, y: number): number; } const add: Add = (x, y) => x + y; console.log(3, 4);//* 7
함수 자체를 미리 선언해놓을 수도 있다.
function add(x: number, y: number): number; //* 위에서 타입 선언을 했을 경우에는 아래서 명시적으로 any 쓰셔도 무방하다.function add(x: any, y: any) { return x + y; } console.log(add(1, 2));
03-02. as
를 통해서 강제 typing 을 할 수 있다.
as
를 통해서 다른 타입의 값을 넣을 있다.let aa = 123; aa = "hello" as unknown as number;
03-03. never
타입
항상 오류를 출력하거나 리턴 값을 절대로 보내지 않음을 의미한다.
function invalid(message: string): never { throw new Error(message); }
03-04. ${}
으로 type
을 확장 정의가 가능하다.
예제
type world = "world" | "hello"; type helloWorld = `hello ${world}`; //* 아래 두개 가능const hi_hello: helloWorld = `hello hello`; const hi_world: helloWorld = "hello world";
03-05. type 정의의 &
연산자
&
가 들어가면 양 옆에 있는 타입을 모두 만족해야 한다는 것이다. 예시는 다음과 같다.type A = { hello: "hello" } & { zeor: "cho" }; const a: A = { hello: "hello", zeor: "cho" };
03-06. type
의 확장 예시
type Animal = { breath: true };
type Poyouryu = Animal & { breed: true };
type Human = Poyouryu & { think: true };
const yjyoon: Human = {
breath: true,
breed: true,
think: true,
};
03-07 interface
, type
, enum
의 네이밍 규칙
앞에
interface
는I
,type
은T
,enum
은E
를 붙인다.예시:
interface IProp {} type TType = string | number; enum EHello { Left, Right, }
1번 과 같은 것들을 안붙인다.
요즘에는 2번을 많이 쓴다. 이유는 커서 올리면 다 보이기 때문이다.
03-08. void
의 두가지 정체
void
는 형식에 따라서 아래 두개로 동작한다.- 함수의 return type으로 void를 설정한 경우: 함수의 반환값이 존재하지 않는다.
interface
에 선언되어있는 메소드의 return type 또는callback
의 return type인 경우: 함수의 반환값이 존재할 수는 있지만 이를 사용하지 않는다.
예시
function a(callback: () => void): void {}//* 이 함수의 리턴값이 없어야 한다.a(() => { return "3"; //* callback 함수의 return 이 void 이지만 여기서 return 값이 있어도 상관없다. }){}; interface Human { talk: () => void; } const human: Human = { talk() { return "abs";//* interface에서 talk 메소드의 리턴 타입이 void. 하지만 return 값이 존재해도 상관없다. }, };
03-09 type guard 기법
어떤 변수의 타입을 체크하는 로직 구현 기법
function numOrStr(a: number | string) { //* a.toFixed(1) --> 에러 발생 (string 일때는 사용할 수 없기 때문)if (typeof a === "number") { //* Type Guard a.toFixed(1); } else if (typeof a === "string") { a.charAt(3); } } numOrStr("123"); numOrStr(1);
class 의 경우에 type Guard 를
instanceof
확용하여 확인한다.class A { aaa() {} } class B { bbb() {} } function aOrB(param: A | B) { if (param instanceof A) { param.aaa(); } else if (param instanceof B) { param.bbb(); } }
type guard 는 커스텀해서 만들 수 있다.
interface Cat { meow: number; } interface Dog { bow: number; } //* 커스텀 타입 가드 (return type 으로 is 를 쓴다.) function catOrDog(a: Cat | Dog): a is Dog { if ((a as Cat).meow) { return false; } return true; } function pet(a: Cat | Dog) { if (catOrDog(a)) { console.log(a.bow); } else { console.log(a.meow); } }
03-10 Object
vs {}
(4.8 버전 이후)
Object
,{}
: 모든 타입을 의미한다. (null과 undefined 는 제외)- unknown을 if 문 안에 넣으면 해당 변수의 타입은
{}
이 된다.
03-11 implemenets
implements
는 형식을 정의해주는 것이다.interface A { a: string; b: string; } class B implements A { b: string = "asd"; a: string = "1"; }
- 위 코드에서 B class 는 A에 정의된 a,b를 모두 구현해놔야 한다.
03-12 제네릭
- 타입을 변수처럼 만드는 것 (아 타입 지금은 모르겠고~ 나중에 정할게~)
function add<T extends string>(x: T, y: T): T {
return x + y;
}
add(1, 2);
add("1", "2");
// <T extends {...}> // 특정 객체
// <T extends any[]> // 모든 배열
// <T extends (...args: any) => any> // 모든 함수
// <T extends abstract new (...args: any) => any> // 생성자 타입
// <T extends keyof any> // string | number | symbol