개발 노트

typescript 본문

Javascript

typescript

Meter216 2023. 3. 23. 20:35

목차

- 기본설정

- 기본타입

- 함수

  - overloading

  - generic

- class

  - interface

 

 

 

 

js에서는 코드를 작성하는 중에 에러를 처리해주지 않는다. 런타임을 돌려야 에러가 난다. 

 

기본 설정

 

node는 ts를 기본적으로 실행 할 수 없다.(해석하지 못한다.)

npm install -g ts-node

ts-node 를 설치함으로 ts-node 를 통해 .ts 파일을 실행시키면 바로 실행 시킬 수 있게 된다.

 

npm init -y
npm install -D typescript

typescript 를 설치하고 난후 

tsconfig.json 파일을 만들어 개인적으로 설정을 해도 되고

 

tsc --init 을 통해 tsconfig 파일을 자동으로 생성 할 수 있다.

 

 

{
  "compilerOptions": {
      "target": "es2016",  
      "module": "commonjs", 
       "esModuleInterop": true, 
       "forceConsistentCasingInFileNames": true, 
        "strict": true,   
        "skipLibCheck": true 
  		}
}

tsconfig.json은 기본적으로 이정도가 설정되어 있다.

target : 기본적으로 컴파일 시 적용될 문법의 버전이다.

module : typescript코드가 사용하는 모듈 시스템이다. node.js 환경에서 사용하는 commonjs설정

esModuleInterop : 설정을 통해 nodejs에서 가져오는 require등을 import와 상호 작용 할 수 있게 한다.

forceConsistentCasingInFileNames : 파일명에 대소문자 구분 적용

strict : 모든 엄격한 타입검사를 할지

skipLibCheck : 모든 선언파일(*.d.ts)의 유형 검사에 대해서 건너뛸지

outDir : 컴파일 된 파일 저장 할 위치 지정

더 자세한 내용의 경우 TypeScript: 문서 - tsc CLI 옵션 (typescriptlang.org) 참조하면 좋다.

 

 


 

기본 타입

function add(num1, num2){
    console.log(1,2)
}

add(1,2)
add()
add(1)
add(1,2,3)
add(123,"world")

js에서는 위 코드를 "실행했을 경우만" 오류를 내줌

 

type 지정을 통해서 미리 에러를 발생시킬 수 있다.

기본 지정 타입 

:number  = 숫자

:boolen = true false

:string  = string

:number[] 혹은 Array<number> =  숫자 배열 (number가 들어가는 곳에 string을 넣으면 스트링 타입이 된다.)

 

 

let a:string = "글자티입"

let b = "글자타입"

a는 타입을 지정해주었기에 a 글자만 입력 할 수 있다.

 

b는 "글자타입"이라는 string 을 입력 해놨기 때문에  typescript 자체에서 b:string 이라고 추론 할 수 있다.

 

기본적으로 모든 타입을 지정하는것보다 추론하게 두는것이 좋다고도 한다.

 

type Person = {
	name:string
	age?:number
}

Person 이라는 타입을 지정했다. 

** 타입 지정을 할 때는 기본적으로 class 처럼 맨 앞글자를 대문자로 해주는게 좋다.

Person 은 name:string 과 age?:number 을 가진 객체형태이다. 

 

사용할 때는

const student:Person = {
	name:"cheol"
    age: 29
}

이렇게 사용 할 수 있다. 

 

여기서 name은 필수기 때문에 name 속성을 써주지 않는다면 student 이렇게 빨간줄이 그여있는 student를 볼 수 있게 된다.

age는 age?로 타입 지정을 해뒀다. 여기서 ?는 있을수도, 없을수도 있다는 표시를 해준다. 

typescript는 name은 필수로 있고 age는 있을수도 없을수도 있는 객체를 달라고 오류를 내 줄 것 이다.

 

 

readonly

 

읽을 수만 있게 하는 속성이다.

type Person = {
    name: string;
    readonly age: number;
};

const student: Person = {
    name: "cheol",
    age: 29,
};

student.name = "kkk";
student.age = 30

여기서 age타입은 readonly를 사용해줬다.

student.name = "kkk"로 바뀔 수 있지만 

student.age = 30 은 typescript 에서 불만을 표시 한다. 이는 읽기 전용 속성으로 "age"에 할당 할 수 없다 고 나온다.

 

 

 

Tuple 

 

:[string, number]  = 첫번째 인자는 string , 두번째 인자는 number

const student:[string,number] = ["cheol", 29]

string과 number 순서에 맞게 넣어줘야한다.

 

 

any 

 

아무 타입이나 쓸 수 있게 된다. > typescript 의 영향에서 벗어나게 될 수 있는 방식이다.

js와 같이 사용할 수 있게 된다. 

 

void = 리턴이 없는 함수의 타입으로 지정 해 줄 수 있음 // 함수에 리턴값이 없으면 자동으로 void 를 인식해준다.

never = 에러를 내는 함수 

function hello(name:string | number) {
	if(typeof name === "string"){
    	name // string
    }else if(typeof name === "number"){
    	name // number
    }else {
        name // never
    }
}

함수

 

overloading

함수가 여러가지의 매개변수 타입을 가지고 있을 때 사용,

매개변수 타입에 따라 다른 동작을 하는 하나의 함수를 만들 수 있게 되는 것.

 

// 매개변수의 타입이 다를 때
type Add = {
    (a: number, b: number): number,
    (a: number, b: string): number
}

const add: Add = (a, b) => {
    if (typeof b === "string") return a; // 다를경우 
    return a + b;
}

add(1,"23")
add(1,2)


// 매개변수의 갯수가 다를 경우 
type Add2 = {
    (a: number, b: number): number,
    (a: number, b: number, c: number): number
}

const add2: Add2 = (a, b, c?: number) => {
    if (c) return a + b + c;
    return a + b;
}

add2(1,2)
add2(2,3)
add2(2,3,4)
type Config = {
	path: string,
	state: number
}

type Push = {
	(config: Config): void,
	(config: string): void
}

const push: Push = (config) => {
	if (typeof config === "string") console.log(config);
	else console.log(config.path);
}

위와같이 사용되는 라이브러리도 존재한다.

 


 

Generic

type Print ={
    (arr:number[]):void;
    (arr:boolean[]):void
}

const prints:Print = (arr)=>{
    arr.forEach((v)=>{console.log(v)})
}

prints([1,2,3,4])
prints([true,false])

prints([1,2,3,4,true,false])

 

위와 같은 코드가 있을 때

 

맨 아래 prints 의 경우에만 오류가 생길 것이다.

prints의 배열의 경우 숫자이거나, boolean 일 경우만 받을 수 있다. 두개의 혼합체를 받을 수 없다.

 

이 경우에는

type Print = {
	(arr:(number | boolean)[]):void
}

이렇게 작성을 하게 되면 당장 해결은 된다

하지만 여기서 만약 다른 타입들까지 추가해야 한다면 코드를 여러번 사용하는 비효율적인 방법이 될 것 이다.

 

이 때 사용할 수 있는것이 Generic 이다.

Generic은 함수의 타입을 작성할 때 기준이 아니라 사용할 때 기준으로 유추 할 수 있도록 미리 설계해두는것이다.

type Print : {
	<T>(arr:T[]):void
}

 

여기서 T 는 간단하게 타입을 받을 변수명 이라고 생각하면 된다. 아무 글자나 넣어줘도 작동한다.
**Type의 약자로 T를 많이 사용하긴 한다.

 

이렇게 작성 할 경우, 앞서 작성했었던

arr([1,2,3,true,false]) 
또한 number | boolean 타입으로 typescript가 유추해서 사용 해 줄 수 있다.

 

Generic 의 경우 라이브러리를 만들거나, 다른 개발자가 사용할 기능을 개발하는 경우 유용하다.

type Example = {
    name:string;
    age:number
}

function Print<T>(a:T){
    return a
}
const a = {name:"chl",age:1}

Print<Example>(a)

예시코드를 이런식으로 작성 할 수 있다,

 

Print는 Example 타입을 T 로 받고 매개변수 a 또한 T 타입으로 받게 되었다.

a의 경우 Example 타입과 맞게 써놓았으므로 인자값으로 받을 수 있게 된다.

이렇게 타입을 지정해서 넣어줄 수도 있다.

 


2. class

 

abstaract = 추상클래스가 되는것 , 예전 Component 구현 당시 추상 메서드를 구현하고, 자식 클래스에서 상세한 구현 코드를 작성했던것을 기억해보면 이해하기 쉽다.

 

public  = 모두가 사용 가능한 메서드를 만드는 것

private = class 내부에서만 활용 가능한 메서드를 만드는것

protecte = 자식 class까지 사용이 가능한 메서드를 만드는 것


 

**interface

 

type과 유사한 기능을 하지만 보통 object의 모양을 정의해주는 용도로 많이 사용한다.

extend를 사용하여 상속이 가능하며 , ** type 의 경우 type & 로 상속이 가능하다.
같은 이름으로 여러개를 만들경우 합체가 가능하다. **type은 불가능하다.

interface User{
    name:string
}

interface User{
    age:number
}

interface User{
    job:string
}

const user:User = {
    name:"cheol",
    age:29,
    job:"student"
}

implements = ts에서만 존재한다. extends와 비슷한 역할을 한다.

 

implements를 사용하여 상속하는 경우 , class 는 상속 받은 것들을 모두 사용해줘야 오류가 나지 않는다.

 

 

 

 

 

연습 할 수 있는 사이트

https://www.typescriptlang.org/play

 

 

 

'Javascript' 카테고리의 다른 글

React 기본  (0) 2023.03.17
React 3.6 정리  (0) 2023.03.06
React - tic tac toe  (0) 2023.02.24
React  (0) 2023.02.23
Promise  (0) 2022.12.21