Typescript 기본 문법2

짝은별·2024년 12월 3일

JS

목록 보기
23/23

generic type(함수)

우선 함수의 전체 타입return 값에 의해 결정된다

function getNum(num):number {
  return num;
}

이 경우 숫자형 변수로 받는다는 가정하에 return값은 무조건 숫자형이다
따라서 function의 타입number가 되는 것이다

함수에서 typeinterface를 미리 지정해서 적용하려면 화살표 함수로 작성해야 한다

funcion getNum(num:number):number {
  return num;
}

type GetNum = (n: number) => number;

interface _GetNum {
  (n:number) : number;
}

const getNum:GetNum = (n) => {
  return n;
}

const getNum:_GetNum = (n) => {
  return n;
}

이번엔 함수의 generic type을 더 살펴보자

매개 변수로 callback function을 받아온다면 이때 generic typecallback function의 return값`에 의해 결정된다

const _delay = <T>(callback:(data:T)=>T, timeout:number = 1000):void => {
  setTimeout(callback,timeout)
}

와 같이 지정할 수 있다 이때 T의 타입callback functionreturn 값에 의해 결정된다

keyof

keyof지정한 타입의 key들매개변수로 전달받을 수 있도록 제한하는 역할을 한다

type Obj = {
  name:string,
  age:number,
  location: {
    lat:number,
    long:number,
  }
};

function getValueOfObj(obj:Obj , key:keyof Obj) {
  return obj[key];
}

이때 매개변수 objObj타입을 만족하는 객체를 아무거나 전달해도 되지만 key 매개변수의 경우 name,age,location중 하나만 사용이 가능하다

이 외의 사용법은 기존에 존재하는 utility들을 확장하여 사용할 수 있다

function validCssProperty<T extends keyof CSSStyleDeclaration>(prop: T): CSSStyleDeclaration[T] {
  return document.body.style[prop];
}

CSSStyleDeclarationCSS의 속성을 모두 포함하는 객체이다
따라서 여기에 존재하는 key값만을 매개 변수로 전달받겠다는 의미이다

이는 generic type이 두 개 이상일때도 사용이 가능하다

const product = {
  id: 1,
  name: "mac-book",
  price: 300,
};

function setProperty<T, K extends keyof T>(product: T, key: K, value: T[K]) {
  product[key] = value;
  return product;
}

type method

Omit

Omit은 타입으로 지정된 key 값들 중에서 지정한 것을 제외한 나머지를 사용한다

type Profile = {
  username: string;
  age: number;
  bio: string;
  id: number;
  name: string;
  email: string;
};

type ProfileOmit = Omit<Profile , 'bio'>;

const user: ProfileOmit = { // const user:Omit<Profile,'bio'>도 가능하다
  username : 'little',
  age: 124,
  id: 1,
  name: 'big',
  email:'little@big.com',
}

Pick

Pick은 타입으로 지정된 key값들 중 원하는 key만 골라서 사용할 수 있다

type Profile = {
  username: string;
  age: number;
  bio: string;
  id: number;
  name: string;
  email: string;
};

type ProfilePick = Pick<Profile , 'username'|'age'|'id'>;

const user: ProfilePick = {
  username:'little',
  age:124,
  id:1,
}

Partial

Partial모든 key 값을 optional로 지정할 수 있다

type Profile = {
  username: string;
  age: number;
  bio: string;
  id: number;
  name: string;
  email: string;
};

type ProfilePartial = Partial<Profile>

const user : ProfilePartial = {
  age:124,
  email:'little@big.com',
}

Readonly

Readonly는 타입의 모든 key값을 override가 불가능하도록 조정한다

type Profile = {
  username: string;
  age: number;
  bio: string;
  id: number;
  name: string;
  email: string;
};

type ProfileReadonly = Readonly<Profile>;

const user: ProfileReadonly = { 
  username : 'little',
  age: 124,
  bio:'bio',
  id: 1,
  name: 'big',
  email:'little@big.com',
}

user.age = 125; // Error!!

Required

Required는 속성에 존재하는 모든 key값을 반드시 사용하도록 조절한다
이는 optional로 정의된 key들도 마찬가지이다

type Profile = {
  username: string;
  age: number;
  bio?: string;
  id?: number;
  name: string;
  email: string;
};

type ProfileRequired = Required<Profile>;

const user: ProfileRequired = { 
  username : 'little',
  age: 124,
  name: 'big',
  email:'little@big.com',
} // Error!!

const user: ProfileRequired = { 
  username : 'little',
  age: 124,
  bio:'bio',
  id: 1,
  name: 'big',
  email:'little@big.com',
} // Success

TS 해석

TS는 기본적으로 웹 브라우저에서 해석하지 않는다
따라서 html파일에 직접적으로 연결하면 해석하지 못해 오류가 발생한다

하지만 번들링 도구(vite)를 사용하면 이를 자동으로 JS로 컴파일 해준다

비동기

비동기는 기본 JS와 비교해도 큰 차이점은 없다
하지만 타입에 주의해야한다

const END_POINT = "https://jsonplaceholder.typicode.com/users";

async function fetchData(url: string): Promise<_User> {
  // get 통신
  const response = await fetch(url);

  const data = await response.json();

  // 데이터 리턴
  return data;
}

const data = await fetchData(END_POINT);

function render(target: Element | HTMLBodyElement = document.body, data: _User): void {
  //데이터 받아오기

  if (Array.isArray(data)) {
    data.forEach((item) => {
      target.insertAdjacentHTML("beforeend", `<li>${item.name}</li>`);
    });
  }

  //렌더링
}

render(document.body, data);

우선 비동기 함수는 항상 Promise객체를 반환하기에 타입 지정이 Promise로 되는 것은 알겠다 하지만 그 내부에 있는 _User는 무엇일까?

바로 비동기로 가져온 Data의 타입을 지정해준 것이다
물론 직접 해석하며 하나하나 type을 만들기엔 더미 데이터가 아닌 통신은 상당히 까다롭다
따라서 extension을 이용해보자

VScodeThunder Client이다

내부에 툴바에서 클릭 후 New Request를 누르면 다음과 같은 화면이 나타난다

우리는 불러오는 데이터의 타입이 무엇인지 확인하기 위해 GET통신을 선택후 불러올 api주소를 입력한다 이후 SEND를 누른다

결과값은 다음과 같다

통신도 정상적으로 이루어졌고 불러온 데이터의 형식도 확인할 수 있다
여기서 code snippet이라고 하는 해당 사진의 오른쪽 위의 {} 아이콘을 클릭한다


이후 generate type을 선택후 Typescript를 선택하면 다음과 같이 친절하게 타입들을 정리해준다

이를 Copy해서 원하는 곳에 Paste하고 사용하면 된다
이후 Promise<>의 내부에 해당 타입을 지정하면 된다

Promise.all()

만약 여러 개의 Promise 객체를 전달받아 이를 하나하나 처리해야할때 유용한 명령어이다
forEach로 배열을 순회하기엔 성능이 나쁘다
따라서 Promise.all()을 사용해 한 번에 처리한다

profile
FE(철 아님) 개발자 꿈꾸다

0개의 댓글