TypeScript 를 쓰는 이유

jeongjwon·2023년 5월 30일
0

SEB FE

목록 보기
52/56

TypeScript

TypeScript 는 일종의 JavaScript 이다. JavaScript + Type 이 붙은 꼴로 상위 확장한 컴파일 언어이다. 동적 타입의 인터프리터 언어인 자바스크립트는 오류 발견이 있지만, 타입스크립트는 정적타입의 컴파일언어로 자바스크립트 코드로 변환해준다. 코드 작성 단계에서 타입을 체크해서 오류를 확인할 수 있고 미리 타입을 결정하기 때문에 실행속도가 빠르다. 이것이 타입스크립트를 사용하는 큰 이유가 아닐까 생각한다.

예를 들면,
function sum(a,b) { return a + b; }
위 함수는 두 개의 숫자를 인자로 받아 합계를 리턴하는 함수를 의도했을 것이다. 하지만 코드상으로는 어떤 타입이든지 인자로 들어갈 수 있지만, 전달인자나 반환값의 타입은 명확하지 않아서 오류를 쉽게 범할 수 있다.

function sum(a: number, b: number){ return a+b; }
정적타입으로 전달인자의 타입을 명확히 해주면 당연히 반환값 또한 명확해진다. 이미 인자로 number 타입만 전달되기 때문에 컴파일 단계에서 쉽게 오류를 파악할 수 있다.

이런 명시적인 타입 지정은 개발자의 의도를 명확하게 코드로 기술할 수 있고, 코드의 가독성을 높이고 예측할 수 있게 하며 디버깅이 쉬워진다.

설치하기

npm init -y
npm install typescript --save-dev
: package.json파일에서 개발단계에서 패키지를 모아놓는 패키지인 devDepndencies속성에 typescript 가 설정된다.

//tsconfig.json
//compilerOptions 내의 속성은 자유롭게 커스텀 할 수 있습니다.

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./dist"
  },
  "include": [
    "src/**/*"
  ]
}

vscode는 기본적으로 typescript에 대한 intellisense 를 지원하는데, 이 intellisense가 .ts파일을 인식하는 방법을 제어하기 위해 tsconfig.json을 작성해야한다. 그리고 tsc
tsconfig.json 파일은 프로젝트를 컴파일하는데 필요한 루트 파일과 컴파일러 옵션을 지정한다.
cimpilerOptions 속성은 생략될 수 있고, 생략이 되면 컴파일러의 기본값이 사용된다.

  • target 은 타입스크립트 파일을 어떤 버전의 자바스크립트로 바꿔줄지 정하는 부분
  • module 은 자바스크립트 파일간 import 문법을 구현할 때 쓸 문법 결정
  • sourceMap은 컴파일된 js 와 ts 간의 맵핑의 유무 결정
  • outDir은 모든 파일을 하나의 파일로 합쳐서 출력할 경우 지정하는 파일명
    inlcude 속성은 프로그램에 포함할 파일 이름이나 패턴을 배열로 지정한다.


문법

1. Type

타입을 직접 지정하여 컴파일 시점에서 에러를 쉽게 잡아낼 수 있다.

let 변수명: 타입 = ___ ;


//숫자형
let oneTwoThree: number = 123;

//문자열 - 큰, 작은 따옴표, 백틱 사용
let code: string = 'helloWorld!';

//boolean
let isDone: boolean = true;

//배열 
let arr1: number[] = [1,2,3];
let arr2: Array<number> = [1,2,3];
let arr3: Array<string> = ['one', 'two', 'three'];

//튜플 - 요소의 타입과 개수가 고정된 배열로 표현
let tupple: [string, number] = ['hello', 5];

//객체 
let user: {name: string, age: number} = {
	name: 'jiwon', age: 26
}

//Any - 어떤 타입도 허용하는 실드 해제 문법
// 타입을 미리 정하기 애매할 경우 사용
// 타입관련 버그 생길 경우 추적하기 어려운 단점
let list: any[] = [1,true, "free"];
list[1] = 100; // 값 재할당 가능

2. 함수

함수 작성시 매개변수의 타입과 반환타입을 명시해야한다.
매개변수의 타입만 명시해주고 반환타입은 명시하지 않아도 타입 추론 기능으로 반환값을 유추가능하다.

//매개변수 O, 반환 O => 타입 추론 기능 x
function concat(a: string, b: string): string {
	return a+b;
}

//매개변수 O, 반환 X => 타입 추론 기능 O
let concat = (a: string, b: string) => {
  return a+b;
}

//void 반환값
let print = ():void => {
  console.log('print');
}

매개변수의 개수에 맞게 전달해야 한다. 만약, 개수보다 적거나 많게 전달하면 에러가 발생한다.

  • 매개변수를 전달해주지 않거나 undefined 로 전달정해놓은 값 default parmater 값으로 동작한다.
  • 있어도 되고 없어도 되는 선택적 매개변수 optional parmeter? 를 추가한다.
//매개변수 값을 정해놓을 경우
function personInfo (name: string, grade=1): string => {
  return `${name} is ${grade} grade.`;
}
personInfo('John');
personInfo('John', undefined);
personInfo('John', 1);
//위 세 함수는 'John is 1 grade.' 로 같은 값을 반환한다.

//선택적 매개변수를 사용하고자 할 때는 ? 를 사용한다.
let sayHello = (firstName: string, lastName?: string): string => {
	return `Hello, ${firstName} ${lastName}`;
}
sayHello('Leo'); //'Hello, Leo undefined' =>두번째 인자를 전달하지 않아도 에러 발생하지 않지만 두번째 인자는 undefined 로 인식
sayHello('Leo', 'Messi'); //'Hello, Leo Messi'

3. 연산자 Union

2개 이상의 타입을 허용하는 경우, 유니언 Union 이라 하고 | 파이프를 통해 타입을 구분한다.

let union: string | number;
union = 'this is union';
union = 1234;
union = false; //에러 발생 => union 은 string 혹은 number 타입만 가능

let arr: (string | number)[] = ['Apple', 1, 2, 'Banana', 'Mango
                               , 3];
let arr: Array<string | number> = ['Apple', 1, 2, 'Banana', 'Mango
                               , 3];

함수의 전달인자로 string or number 로 받는데, 유니언은 타입 추론 가능하므로 타입과 관련된 API를 쉽게 자동완성으로 얻어낼 수 있다.

하지만 주의해야할 점이 있다.

interface Person {
  name: string;
  age: number;
}
interface Developer {
  naem: string;
  skill: string;
}
function introduce(somone: Person | Developer){
  someone.name; // O 공통 속성이므로 정상 동작
  someone.age; // X 타입 오류
  someone.skill; // X 타입 오류
}

다음과 같은 introduce 함수의 전달인자로 Person 이나 Developer 인터페이스를 사용하는데, 두 인터페이스에 공통 속성인 name 만 접근할 수 있고, age 나 skill 에는 접근할 수가 없다. 타입스크립트 관점에서는 함수를 호출하는 시점에서 Person 이 올지 Developer 가 올지 미리 알수가 없기 때문이다.

4. 연산자 Intersection

& 를 사용해 2개 이상의 타입을 조합하는 경우, 인터섹션 Intersection 이라고 한다.
새로운 타입을 생성하지 않고 기존의 타입들로 조합할 수 있다.

let value: string&number&boolean;
//value 는 string, number, boolean 타입을 모두 받을 수 있다.
interface Person {
  name: string;
  age: number;
}
interface Developer {
  name: string;
  skill: string;
}

const neo: Person & Developer = {
  name: 'Neo',
  age: 85,
  skill: 11,
};

&를 이용해 두 인터페이스를 합쳐 하나의 타입을 구성하는 neo 는 union으로 공통 속성만 접근할 수 있는 것과는 반대로 각각의 인터페이스의 속성 name, age, skill 에 모두 접근가능하다.

0개의 댓글