게으른개발너D

Overview of Typescript 본문

개발/TypeScript

Overview of Typescript

lazyhysong 2023. 4. 3. 20:44

✨ How Typescript Works ✨

 

타입스크립트는 Strongly Typed(강타입) 프로그래밍 언어이다.

이런 언어는 코드를 다 작성하고 나면 코드를 컴파일 해서 0101로 바꿔주거나, 어셈블리 코드나 바이트 코드가 되기도 한다.

타입스크립트에서는 작성한 코드가 자바스크립트로 변환된다.

변환하는 이유는 브라우저가 타입스크립트가 아니라 자바스크립트를 이해하기 때문이다.

참고로 Node.js는 타입스크립트와 자바스크립트 언어를 둘 다 이해할 수 있다.

타입스크립트가 제공해주는 보호는 타입스크립트 코드가 자바스크립트로 변환되기 전에 발생한다.

타입스크립트가 우리 언어를 미리 확인한 후 바보같은 실수가 일어나지 않도록 확인을 해준다.

그리고 에러가 있다면 자바스크립트로 변환을 해주지 않는다.

 

예를 들어 이렇게 작성한다면

[1, 2, 3, 4, 5] + false;

자바스크립트에서는 결과가 '1, 2, 3, 4, 5, false'라는 걸로 나왔겠지만 

 

타입스트립트에서는 이런 에러가 뜰 것이다.

Operator '+' cannot be applied to types 'number[]' and 'boolean'

 

 

✨ Implicit Types vs Explicit Types ✨

 

typescript는 타입 설정하는 방법이 두가지 있다.

하나는 데이터와 변수의 타입을 명시적으로 정의할 수 있고, 아니면 그냥 javascript처럼 변수만 생성하고 넘어가도 된다.

여기서 좋은 점은 typescript가 타입을 추론해 준다는 것이다.

 

let a = "hello";

예를 들어 이렇게 하는 것 만으로도 Typescript는 a의 타입이 string이라는 걸 추론해 줄 것이다.

 

다른 옵션은 Typescript에게 구체적으로 말해주는 것이다.

let b : boolean = "x";

이렇게 boolean이라고 정의해놓고 string 값을 넣으면 에러가 날 것이다.

: boolean은 type checker와 대화하는 방법이다. 즉, typescript 언어이다.

 

 

 

✨ Types of TS ✨

 

const player : {
  name: string,
  age: number
} = {
  name: "hwayeon"
}

이런식으로 player object의 타입을 정해줄 수 있는데, 이렇게 적으면 에러가 날 것이다.

player 안에 type으로 정의해 준 age의 값이 없기 때문이다.

 

age의 타입을 정의하였지만 age가 있는 player도 있고 없는 player도 있게 만들려면 어떻게 해야할까?

 

이러한 선택적 타입 설정은 age 뒤에 ?를 붙여주면 된다.

const player : {
  name: string,
  age?: number
} = {
  name: "hwayeon"
}

age는 number이기 때문에 ?를 붙이면 number | undefined 란 뜻이 된다.

 

 

같은 종류의 타입을 쓰는 오브젝트들이 여러게 있다면 어떻게 정의해야 할까??

type Player = {
  name: string,
  age?: number,
}

const hwayeon : Player = {
  name: "hwayeon",
}

const hynju : Player = {
  name: hynju,
  age: 12,
}

여기까지 const나 let에 type을 할당하는 방법을 알아보았다.

 

 


이제 함수를 하나 만들 것인데, 그 함수는 player의 object를 만들고 그 결과로 player를 반환할 것이다.

function playerMaker(name: string) {
  return {
    name
  }
}

이렇게 name을 가지고 있는 Player라는 object를 return하는 함수를 만들었다.

하지만 타입스크립트는 이 함수가 object 값을 return 한다고 생각한다.

const hwayeon = playerMaker("hwayeon");
hwayeon.age = 12;

따라서 이렇게 적을 시 타입스크립트는 에러를 띄운다.

 

우리는 Player 타입을 return 하고싶다고 정의하고 싶다.

 

우리가 할 일은 괄호 뒤에 variable들과 argument에 해줬던 그대로 하면 된다.

 

function playerMaker(name: string) : Player {
  return {
    name
  }
}

이제 위의 hwayeon.age 는 에러가 발생하지 않는다.

 


 

원한다면 readonly 속성(property)을 추가해 줄 수 있다.

이건 요소들을 '읽기 전용'으로 만들 수 있다.

type Player = {
  readonly name: string,
  age?: number
}

readonly로 만들고싶은 속성 앞에 readonly를 붙여주기만 하면 된다.

이렇게 만든 후 hwayeon.name = "hi" 라고 정의하면 오류가 생긴다.

 

배열에 적용한 예를 보자

const numbers : readonly number[] = [1, 2, 3, 4];

numbers.push(1);

 

위의 줄처럼 readonly로 정의해 놓고 그 배열에 push를 하면 오류가 생긴다.

 


Array를 생성할 수 있는 Tuple이라는 것을 알아보자

 

Tuple은 최소한의 길이를 가져야 하고, 특정 위치에 특정 타입이 있어야 한다.

const player: [string, number, boolean] = ["nico", 1, true];

const player: readonly [string, number, boolean] = ["nico", 1, true];

아래줄처럼 readonly를 넣어줄 수도 있다.


이런 것도 됨

let a : undefined = undefined;
let b : null = null;

 

만약 비어있는 array를 정의해주면 typescript는 type을 무엇으로 정의할까?

let a = [];

이럴경우 any[] 타입으로 정의한다.

 

any는 Typescript로부터 빠져나오고 싶을 때 쓰는 타입이다.

any는 말 그대로 아무 타입이나 될 수 있기 때문이다.

 

Typescript 설정에 any 사용을 막기위해 추가할 수 있는 몇 가지 규칙이 있다.

하지만 any는 Typescript에 존재하고 우린 그걸 사용하는 방법을 배울 필요가 있다.

 

최대한 any를 쓰지 않는 것이 좋다. typescript의 보호에서 빠져나오기 때문이다.

const a: any[] = [1, 2, 3, 4];
const b: any = true;

a + b

any를 쓰면 이.. 이게.. 작동한다!!

 


 

이번엔 typescript의 매우 독특한 타입을 몇 가지 살펴볼 것이다.

 

만약 API로부터 응답을 받는데 그 응답값의 타입을 모르겠다면 'unknown'이라는 타입을 쓸 수 있다.

let a: unknown;

let b = a + 1;

만약 이렇게 쓴다면 a의 타입은 unknown이므로 타입스크립트가 허용을 안해줄 것이다.

그럴 경우 a의 타입을 한번 체크해 줘야한다.

if(typeof a === 'number') {
  let b = a + 1
}

if(typeof a === 'string') {
  let b = a.toUpperCase();
}

 


void는 아무것도 return 하지 않는 함수를 대상으로 사용한다.

function hello() {
  console.log('x');
}

이럴 경우 hello라는 함수의 타입은 void가 된다.


이번엔 never라는 type에 대해 알아보자.

 

never는 함수가 절대 return하지 않을 때 발생한다.

예를들어 함수에서 exception(예외)이 발생할 때 말이다.

function hello(): never {
  throw new Error("error!")
}

 

 

never는 타입이 두 가지 일 수도 있는 상황에 살생할 수도 있다.

 

예를들어 hello에서 name을 받고 이게 string이거나 number라고 하자

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

이렇게 정의할 경우, 첫번째 조건에 있는 name은 string이고, 두번째는 number이고, 세번째는 never이다.

 

 

Comments