반응형
타입스크립트
- Deno라는 런타임 환경에서 돌아감
- js로 변환 후 Node.js 런타임에서 실행 → 이 과정을 컴파일이라함 (java와 다름, 단순 컴파일)
설치
sudo npm install -g typescript
// version 확인
tsc -v
// 실행하기 위해 npm package 설치 -> javascript(node.js) 프로젝트 만들기
npm init
// tsc 실행 할 때 컴파일 옵션을 정하기 위해 config 파일 만들기
tsc --init
ts.config.json 설정
{
"compilerOptions": {
"include": ["**/*.ts"],
"exclude": ["node_modules"],
}
}
- include → 어떤 타입스크립트 파일을 자바스크립트 파일로 변환할거냐
- "include": ["**/*.ts"], → 모든 폴더에 모든 파일을 변환할거임
- exclude → 어떤 타입스크립트 파일을 변환 안할거냐
- "exclude": ["node_modules"],
- compilerOptions → 모든 타입스크립트 옵션들이 들어가있음
TSConfig Reference - Docs on every TSConfig option
실행
// ts파일 -> js파일로 변환
tsc 파일이름.ts
// js파일 생기고 그것을 node나 nodemon으로 실행
// 한 줄로 실행
tsc 파일이름.ts && nodemon 파일이름.js
// 모든 파일 변환
tsc
타입 주석
const a: number = 1;
const b: string = 'hi TS';
any - 다들어감 어떤 타입이든.. (쓰지않기 X)
number - interface, Long(bigint, smallint)
string - ``, '', ""
boolean - true, false (0,1 미포함)
object - {}, 객체의 any -> 모든 에러의 근원 (쓰지않기 X)
- Number, String 이런거는 형 변환 함수이므로 타입을 명시할 때는 소문자로 적는다
타입 추론
let a = 1;
인터페이스
- 명세, 타입, 클래스를 만들 때 사용
interface Person {
name: string;
age: number;
city?: string; // ?는 값이 있을 수도 있고 없을 수도 있다.
}
const man = {
name: 'kky',
age: 26,
};
function prt(params: Person) {
console.log(params.name);
//console.log(params.city ??'suwon'); === params?.city ? params.city : 'suwon';
}
prt(man);
익명 인터페이스 - 1번만 쓸 때
const man: {name:string; age:number; city?: string} = {
name: 'kky',
age: 26,
};
function prt(params:any) {
console.log(params?.city ?? 'suwon');
}
prt(man);
배열
const arr1:number[] = [1, 2, 3];
const arr2:Array<number> = [1, 2, 3];
const arr3:string[] = ['a', 'b', 'c'];
const arr4:Array<string> = ['a', 'b', 'c'];
인터페이스 배열
interface Person {
name: string;
age: number;
city?: string;
}
const arr5: Person[] = [
{
name: 'kky',
age: 26,
city: 'suwon',
},
{
name: 'hhm',
age: 26,
city: 'juan',
},
];
arr5.forEach((e) => console.log(e));
// arr5.forEach((e) => console.log(e?.city ?? 'default!'));
튜플
- 배열의 길이와 원소를 바꿀 수 없다, 불변성 유지
- 논리적 자료구조 실체가 없다.
const arr6: [number, string, object, any[]] = [1, 'hi', {}, []];
console.log(arr6);
// 값은 들어간다.
arr6.push('a');
console.log(arr6);
enum, literal
enum categoryEnum {
H = 'H', // 무조건 할당해야함 초기화를 하지 않으면 0,1,2 순으로 자동으로 값을 가짐
K = 'K',
S = 'S',
}
const category: categoryEnum = categoryEnum.H;
function cate(category: any) {
if (category === 'H') {
console.log('5% 할인');
} else if (category === 'K') {
console.log('10% 할인');
} else if (category === 'S') {
console.log('80% 할인');
} else {
console.log('서버 멈춤');
}
}
cate(category);
enum과 literal의 차이
enum sexEnum {
Male = 'Male',
Female = 'Female',
}
const sex: 'Male' | 'Female' = 'Male'; // 2개중 무조건 하나를 넣어야함
const sex2: sexEnum = sexEnum.Male; // enum
- literal은 1번만 사용할 때 쓰기 좋음 그 외는 enum
- js에서 enum은 함수로 구현 (enum이 실제로 없기 때문)
함수 - function
function add(a: number, b: number): string {
return String(a + b);
}
console.log(add(10, 20));
⭐️ return 문이 없거나 return; 인 경우 - void
function add(): void {
console.log('리턴 문이 없습니다.');
}
add();
- 함수의 파라미터는 () 안에서 타입 선언
- 반환값 타입 선언은 () 옆에서 선언
화살표 함수의 타입 선언
const minus: (a: number, b: number) => string = (a, b) => String(a - b);
console.log(minus(20, 10));
기본 구조
const 함수명:(매개변수 타입) => 리턴 타입 = (매개변수 타입):리턴타입 => {
return () => {}
}
const multiple:(a:number,b:number) => () => number = (a:number,b:number):() => number => {
return () => {return a * b * 2};
}
type - 함수 or 타입이 길어질 때 사용
- 기본 구조
- type typeName(아무이름) = any(타입);
- type을 사용하여 리팩토링 해보기
minus 함수
const minus: (a: number, b: number) => number = (a:number, b:number):number => a - b;
console.log(minus(20, 10));
type addFunc = (a: number, b: number) => number;
const minus: addFunc = (a: number, b: number): number => a - b;
console.log(minus(20, 10));
multiple 함수
const multiple:(a:number,b:number) => () => number = (
a:number,
b:number
):() => number => {
return () => {
return a * b * 2
};
}
type returnFunc = () => number;
type multiFunc = (a:number,b:number) => returnFunc;
const multiple: multiFunc = (
a: number,
b: number
): returnFunc => {
return () => {
return a * b * 2;
};
};
에러문
- 기본 에러 코드 예시
function sendErr(): void {
console.log('에러 발생');
return;
}
const result = sendErr();
throw는 return과 비슷 - 에러코드를 보내줌
function sendErr(): void {
throw { errorCode: 500, message: 'err' };
console.log('에러 발생');
return;
}
const result = sendErr();
console.log(result);
클래스 - 접근 제한자 getter, setter
class UserInfo {
public name: string;
protected age: number;
private _city: string;
constructor(name: string, age: number, city: string) {
this.name = name;
this.age = age;
this._city = city;
}
getName(): string {
return this.name;
}
getAge(): number {
return this.age;
}
_getCity(): string {
return this._city;
}
_setCity(newCity: string) {
this._city = newCity;
}
}
const user:UserInfo = new UserInfo('ky', 26, 'suwon');
console.log(user.getName());
console.log(user._getCity());
user._setCity('juan');
console.log(user._getCity());
- 자바스크립트에서느 protected는 관례적 _ , private는 관례적 #을 붙이는데 타입스크립트는 private 앞에 _를 붙여준다.
- 클래스는 new 클래스명으로 인스턴스를 만들 수 있지만, 타입으로도 쓸 수 있다.
클래스 - readonly
- 읽기 전용
class LoginDataTransferObject{
/*
public readonly ID;
public readonly PW;
constructor(ID: string, PW:number){
this.ID = ID;
this.PW = PW;
}*/
// 생성자 함수에서만 접근 제한자 사용가능
constructor(public readonly ID: string, public readonly PW: number){
this.ID = ID;
this.PW = PW;
}
}
const loginDTO:LoginDataTransferObject = new LoginDataTransferObject('hi',1234);
loginDTO.ID = 'set'; // err!
console.log(loginDTO);
? → 값이 있을 수도 있고 없을 수도 있을 때
class LoginDataTransferObject {
public ID;
public PW?;
constructor(ID: string, PW?: number) {
this.ID = ID;
if (PW) this.PW = PW;
}
}
const loginDTO = new LoginDataTransferObject('hi');
// loginDTO.ID = 'set';
console.log(loginDTO);
추상 클래스
- 추상 클래스는 특정 클래스의 상속 대상이 되는 클래스이며 좀 더 상위 레벨에서 속성, 메서드의 모양을 정의
abstract class Developer {
abstract coding(): void; // 'abstract'가 붙으면 상속 받은 클래스에서 무조건 구현해야 함
drink(): void {
console.log('drink sth');
}
}
class FrontEndDeveloper extends Developer {
coding(): void {
// Developer 클래스를 상속 받은 클래스에서 무조건 정의해야 하는 메서드
console.log('develop web');
}
design(): void {
console.log('design web');
}
}
const dev = new Developer(); // error: cannot create an instance of an abstract class
const josh = new FrontEndDeveloper();
josh.coding(); // develop web
josh.drink(); // drink sth
josh.design(); // design web
대수 타입 - union, intersection
// 1. union - 합집합
let nameAge: string | number;
nameAge = 'kky';
nameAge = 26;
// 2. intersection - 교집합
interface IName{
name:string
}
interface IAge{
age:number
};
const age: IName & IAge = {
name: 'kky',
age:26,
}
Key 값을 유동적으로 바꾸고 싶을 때
// interface IName {
// name: string;
// }
// interface ISchool {
// school: string;
// }
// interface ICity {
// city: string;
// }
interface ISuperKey {
[key: string]: string;
}
function prt(params: ISuperKey) {
if ('name' in params) {
console.log(params.name);
} else if ('school' in params) {
console.log(params.school);
} else if ('city' in params) {
console.log(params.city);
}
}
prt({ name: 'kky' });
interface의 타입을 가진 키만 갖고 싶을 때
interface IBook {
title: string;
publisher: string;
price: number;
author: string;
}
function prt1(params: IBook, key: keyof IBook) {
console.log(params[key]);
}
prt1(
{
title: 'ts',
publisher: '인프런',
price: 10000,
author: 'kky',
},
'title'
);
- keyof 를 적는다.
인터페이스 합치기
interface IUser {
name: string;
age: number;
}
interface IBook {
title: string;
price: number;
}
interface ICart {
userName: string;
userAge: number;
}
interface IUserBookCart {
user: IUser;
book: IBook;
cart: ICart;
}
function searchBook(params: IUserBookCart['book']) {
console.log(params);
}
searchBook({
title: '객체지향의 사실과 오해',
price: 20000,
});
'Backend > JS & TS' 카테고리의 다른 글
자바스크립트 - part 4 (0) | 2023.03.23 |
---|---|
자바스크립트 - part 3 (0) | 2023.03.23 |
자바스크립트 - part 2 (0) | 2023.03.23 |
자바스크립트 - part 1 (0) | 2023.03.23 |
댓글