typescript 사용 이유와 문법 특징

BiBi·2022년 6월 21일

찍먹

목록 보기
1/4


1. 타입스크립트를 사용하는 이유

안정성때문이다. 코드를 작성할 때 타입 체크를 통해 버그가 줄어들고 개발자 경험을 좋게 만들어준다. 따라서 런타임 에러가 줄어들고 결국엔 생산성도 높인다.

javascript는 유연한 언어이다.

ex 1)

[1,2,3,4]+false // 결과 : 1,2,3,4false

너무 flexible 한 나머지 위와 같은 이상한 코드를 허용한다.

ex 2)

const add = (a,b) => return a+b;

const result = add(1);

a,b 두개의 값이 필요하지만 a값만 넘겨도 오류가 발생하지 않는다.

이러한 런타임 에러는 코드를 실행하기 전에 오류가 발생한다는 것을 알려주는 것이 이상적이다. 그래서 코드를 실행하기전에 오류를 잡아내자라는 목표로 typescript가 등장하게 되었다.



2. 타입스크립트란?

typescript = strongly typed 프로그래밍 언어이다.
typescript에서 코드를 확인하고 컴파일 과정에서 에러가 있다면 컴파일을 하지 않고 에러가 없다면 javascript로 코드를 변환한다.



3. 타입스크립트의 타입 시스템

  1. 데이터와 변수의 타입 명시적 정의
  2. Javascript처럼 변수만 생성 -> typescript가 자동으로 타입 추론

타입 종류

  • number
  • string
  • boolean
  • ...[] : array
  • optional type
    ex) const player : {name:string, age?:number} 에서 age는 number이거나 undefined이다. 사용할 때는 if(player.age && plyer.age < 10) 이렇게 조건체크가 필요함.

문법

const 변수명 : type = ... 형태

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

const playerOne:Player = {name:'one'} //type Player 사용
const playerTwo:Plyer = {name:'two', age:12}

//함수
function playerMaker (name:string):Plyaer{	//return 타입이 Player
  return {name} 
}

//화살표 함수
const playerMaker = (name:string):Player=>({name});
const chaeyeon = playerMaker('chaeyeon');
yeon.age=12;

문법 특징

1. readonly 속성

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

numbers.push(1) //에러 발생

2. tuple

array내 type이 다를 때 사용

const player:[string,number,boolean] = ['yeon',24,true]

3. any

typescript의 제약에서 빠져나오고 싶을 때 사용. typescript의 보호장치를 비활성화 한다.

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

a+b //오류 발생하지 않음

4. unknown

변수의 타입을 미리 알지 못할 때 사용

let a:unknown; 

if(typeof a==='number') let b = a+1;
if(typeof a==='string') a.toUpperCase();

5. void

아무것도 return하지않을 때 사용하지만 꼭 써줄 필요없이 생략가능하다

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

6. never

함수가 절대 return값이 없을 때 사용한다.

function hello(name:string|number):never{
  throw new Error('X'); 
}


4. 타입스크립트의 function

Call Signatures

//call signature 없이
//이 함수는 number type을 return 한다.
const add =(a:number, b:number)=> a+b;

//call signature 사용
type Add = (a:number, b:number)=>number;
const add:Add = (a,b)=> a+b;

call signature의 장점

함수를 구현하기 전에 타입을 만들고 함수가 어떻게 작동하는지 서술 가능.
코드를 짤 때 함수의 타입을 설명하고 코드룰 구현하면서 프로그램을 디자인할 때 타입을 먼저 생각하고 분리해서 구현이 가능하다.


overloading

다른 사람이 만든 외부 라이브러리를 사용할 때 오버로딩을 많이 사용한다.
오버로딩은 함수가 서로 다른 여러개의 call signatures를 가지고 있을 때 발생한다.

//param 타입이 다를 때
type Add = {
  (a:number, b:number):number,
  (a:number, b:string):number
}

const add:Add=(a,b)=>{
  if(type of b==='string') return a;
  return a+b;
}

//param 갯수가 다를 때
type Add = {
  (a:number, b:number):number,
  (a:number, b:number, c:number):number	//여기서 c는 option이 된다.
}

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

polymorphism

polymorphism = many+structure => 여러가지 다른 형태

//배열을 받고 배열의 요소를 하나씩 print하는 함수
type SuperPrint = {
  (arr:number[]):void
  (arr:boolean[]):void
  (arr:string[]):void
  ...
}

const superPrint:SuperPrint=(arr)=>{
  arr.forEach(i=>console.log(i))
}

superPrint([1,2,3,4]);
superPrint([true,false]);
superPrint(['1','2','3']);

위의 코드에서 배열이 number인지 boolean인지... 모든 type에 대해 작성하는 것은 비효율적이다. 이때 generic type을 사용할 수 있다.


type SuperPrint = {
  //<Generic>, <T>, <V> ... 아무거나 사용가능 하다
  <TypePlaceholder>(arr:typePlaceholder[]):void
}

const superPrint:SuperPrint=(arr)=>{
  arr.forEach(i=>console.log(i))
}

superPrint([1,2,3,4]);
superPrint([true,false]);
superPrint(['1','2','3']);
  • concrete type : number, boolean, string 같은 것들
  • generic : type 의 placeholder

generic은 call signature를 작성할 때 들어올 확실한 타입을 모를 때 사용할 수 있다. generic을 이용해서 작성하면 typescript가 자동으로 타입을 유추한다.


Generics

generic과 any의 다른점은 generic은 타입스크립트의 보호를 받지만 any는 받지않는 다는 것이다.
generic은 개발자가 요구한 대로 signature를 생성하게 해주는 도구이다.

//generic 여러개 사용하기
type SuperPrint= {
  <T, M>(a:T[],b:M):T 
}

const superPrint:SuperPrint=(a,b)=>{
  return a[0]; 
}

const a = superPrint([1,2,3,4], 'x');

//type 확장하기
type Player<E>={
  name:string
  extraInfo:E
}

type Extra={
  age:number 
}

type exPlayer = Player<Extra>

const yeon:exPlayer={
  name:'chaeyeon',
  extraInfo:{
    age:24 
  }
}
profile
프론트엔드 개발자

0개의 댓글