[TypeScript] OVERVIEW OF TYPESCRIPT #2.2 - #2.4

uxolrv·2022년 12월 13일
1

nomadCoder - TypeScript

목록 보기
3/9
post-thumbnail

📌 Types of TS (part 1)


💡 optional parameter (선택적 변수)

🔎 모든 player가 이름은 가지고 있지만, age는 특정 인물만 가지고 있다면?

const player : {
  name:string,
  age?:number // age를 optional한 값으로
} = {
  name:"nico"
}

playername:stringage:number를 가진 object


age를 선택적 변수로 만들고 싶다면 ?를 붙이면 된다.

// player 호버 시
const player : {
  name:string;
  age?:number | undefined;
}

age는 number 타입이거나, undefined!


🔎 이때, player.age 값을 사용하려 하면?

if (player.age < 10) { // Err: Object is possibly 'undefined'
  something...
}

타입스크립트는 player.ageundefined일 수도 있다는 사실을 안다.

if (player.age && player.age < 10) {
  something...
}

player.age가 존재하는 지 확인하는 과정을 거친 후, if문 실행하도록 작성해야 한다.




💡 Alias 타입

🔎 만약, player가 엄청나게 많다면?

const playerNico : {
  name:string,
  age?:number
} = {
  name:"nico"
}

const playerLynn : {
  name:string,
  age?:number
} = {
  name:"lynn"
  age:12,
}

...

똑같은 타입을 반복해서 계속 적어줘야 한다.
⇒ 이 때 사용할 수 있는 것이 Alias 타입!


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

const nico : Player = {
  name:"nico"
}

const lynn : Player = {
  name:"lynn"
  age:12,
}

...

Player라는 타입을 정의하여 사용하면 코드를 반복하지 않아도 된다!


type Age = number;

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

원한다면 age의 타입만을 따로 정의할 수도 있다.
(물론 위 코드에서 이렇게 할 필요는 없음)




💡 함수의 arguments 타입과 return 타입 지정

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

// arguments의 타입을 지정
function playerMaker(name:string){
  return {
    name // 인자로 들어온 name
  }
}

const nico = playerMaker("nico")
nico.age = 12 // Err

현재 playerMakername이라는 요소만 가지고 있는 object를 return하기 때문에 age를 추가할 수 없다.


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

// ✨ 함수의 return값에 Player라는 타입을 지정!!
function playerMaker(name:string) : Player {
  return {
    name
  }
}

const nico = playerMaker("nico")
nico.age = 12

playerMaker는 인자로 name:string을 받고, Player 타입을 return하는 함수

이제 TypeScript는 nicoPlayer 타입임을 알기 때문에 age 값을 추가할 수 있게 된다.


🔎 화살표 함수에서는?

const playerMaker = (name:string) : Player => ({name})

위처럼 작성 가능하다!








📌 Types of TS (part 2)

💡 readonly 속성

요소들을 '읽기 전용'으로 만들 수 있는 속성


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

const playerMaker = (name:string) : Player => ({name})
const nico = playerMaker("nico")

nico.name = "las" // Err: cannot assign to 'name' because it is a read-only property

namereadonly 속성을 부여했기 때문에, name 값을 변경할 수 없게 된다!


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

numbers.push(1) // Err: Property 'push' does not exist on type 'readonly number[]'
name.filter(...)
name.map(...)

readonly 속성이 부여된 타입에 push는 할 수 없지만, map이나 filter는 가능하다.

map, filter는 원본 배열을 변경시키지 않으므로! (immutability, 불변성)




💡 Tuple

최소한의 길이를 갖고, 특정 위치에 특정 타입이 있는 배열을 생성


🔎 요소의 개수와 타입 순서가 정해진 배열을 타입스크립트로 만들려면?

이름(string), 나이(number), 챔피언여부(boolean) 순으로 만들어진 배열을 만들어보자!

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

player[0] = 1 // Err: Type 'number' is not assignable to type 'string'

만약 player의 0번째 인덱스(string)을 number 값으로 변경하려 한다면, 에러가 발생하게 된다.


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

물론, readonly 속성과 함께 사용할 수도 있다!
함께 사용할 경우 배열의 어떠한 값도 변경할 수 없게 된다.




💡 undefined, null

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

JavaScript에도 존재하는 타입으로, undefinedundefined, nullnull




💡 any

TypeScript로 빠져나오고 싶을 때 사용하는 타입

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

any 타입을 사용할 경우, TypeScript의 보호장치를 비활성화 시키므로 사용을 권장하지는 않는다.


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

a + b

any 타입을 사용할 경우, 위처럼 number로 이루어진 배열에 boolean 타입을 더하는 것을 허용하게 된다.
⇒ JavaScript로 작업하는 것과 동일해지는 것!








📌 Types of TS (part 3)

💡 unknown

어떤 타입인 지 모를 때에 사용하는 타입
ex. API 통신 시, 응답의 타입을 모를 경우


let a : unknown;
let b = a + 1 // Err: Object is of type 'unknown'

unknown 타입을 사용할 경우, 어떤 작업을 하려면 이 변수의 타입을 먼저 확인해야 하는 방식으로 TypeScript의 보호를 받게 된다.

unknown 타입을 사용하려면 타입을 먼저 확인하는 코드를 작성해야 한다.


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

위 코드는 if문 범위 안에서 a의 타입이 number인 지 확인하였기 때문에, 에러가 발생하지 않는다.


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

마찬가지로, a의 타입이 string인 지 확인하였기 때문에 a.toUpperCase()가 가능하다.




💡 void

아무것도 return하지 않는 함수를 대상으로 사용하는 타입
void 타입 변수에는 null과 undefined만을 할당할 수 있다.

보통 void는 따로 지정해 줄 필요가 없다.
⇒ TypeScript가 이 함수는 아무것도 return하지 않는다는 것을 자동으로 추론하기 때문에!


function hello() { // function hello(): void
  console.log('x')
}

const a = hello();
a.toUpperCase(); // Err: property 'toUpperCase' does not exist on type 'void'

hello 함수의 경우, void는 따로 지정하지 않았지만, TypeScript가 void 타입임을 추론하였다.

void 타입을 리턴하기 때문에 toUpperCase()를 실행할 시 에러가 발생한다.




💡 never

함수가 영원히 return하지 않을 때 사용하는 타입
ex. 에러를 발생하는 함수, 무한 루프 함수 ...

function hello(): never{
  return "X" // Err: Type 'string' is not assignable to type 'never'.
}

never를 return 타입으로 지정한 함수에서는 return 값을 설정할 수 없다.


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

위와 같이 에러를 throw하거나, 무한 루프 함수일 때 주로 사용한다.


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

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

함수 hello는 string이거나 number 일 수 있는 name을 인자로 받는 함수이다.

if문으로 name이 string인 경우와 number인 경우를 모두 확인해주었기 때문에, else문의 name은 never 타입이다.

이때, 타입이 string이나 number로 올바르게 들어왔을 경우 else문은 절대 실행되지 않는다.








profile
안녕하세연🙋 프론트엔드 개발자입니다

0개의 댓글