카테고리 없음

Type script 배우기

김솜뭉치 2022. 6. 11. 23:47

타입스크립트를 써야하는 이유?

  • 에러의 사전방지
  • 코드 가이드 및 자동완성(개발 생산성 향상)

 Fundamentals

기본 타입

  • String / Number / Boolean / Array / Tuple :  배열의 길이 고정, 각 요소의 타입이 지정되어 있는 배열 / Enum : 특정 값(상수) 들의 집합 / Any : 모든 타입에 대해서 허용 /  Void : 변수에는 undefined와 null만 할당하고, 함수에는 반환 값을 설정할 수 없음 / Never : 함수의 끝까지 실행되지 않음

함수

  • 함수의 기본적인 타입
function sum(a: number, b: number): number {
  return a + b;
}
  • 함수의 인자 : 함수의 인자를 모두 필수 값으로 간주, undefined 나 null도 인자로 넘겨야 함. 정의된 매개변수의 값만 받을 수 있고, 추가로 인자를 받을 수 없다. 
function sum(a: number, b: number): number {
  return a + b;
}
sum(10, 20); // 30
sum(10, 20, 30); // error, too many parameters
sum(10); // error, too few parameters

// 정의된 매개변수의 갯수만큼 인자를 넘기지 않아도 되는 js의 특성을 살릴 때
function sum(a: number, b?: number): number {
  return a + b;
}
  • This : JS의 this가 잘못 되었을 때 감지할 수 있다. 콜백으로 함수가 전달되었을 때의 this를 구분해줘야 함. 

인터페이스 : 상호 간에 정의한 약속 또는 규칙

let person = { name: 'Capt', age: 28 };

function logAge(obj: { age: number }) {
  console.log(obj.age); // 28
}
logAge(person); // 28

// 인터페이스 적용
interface personAge {
  age: number;
}

function logAge(obj: personAge) {
  console.log(obj.age);
}
let person = { name: 'Capt', age: 28 };
logAge(person);

> 인터페이스에 정의된 속성/타입의 조건만 만족하면, 객체의 속성 갯수가 더 많아도 상관 x, 속성 순서를 지키지 않아도 됨

 

  • 옵션 속성 : 인터페이스에 정의되어 있는 속성을 다 사용하지 않아도 됨
interface 인터페이스_이름 {
  속성?: 타입;
}

// 장점
인터페이스를 사용할 때 속성을 선택적으로 적용 가능, 정의되어 있지 않은 속성에 대해 인지 시킴
  • 읽기 전용 속성 : 인터페이스로 객체를 처음 생성할 때만 값을 할당하고 그 이후에는 변경할 수 없는 속성
interface CraftBeer {
  readonly brand: string;
}
  • 읽기 전용 배열 : 배열을 선언할 때 ReadonlyArray<T> 타입을 사용하면 읽기 전용 배열을 생성할 수 있음
  • 함수 타입 / 클래스 타입을 정할 수 있고, 인터페이스 간 확장/상속 가능 

이넘(Enums) : 특정 값들의 집합

  • 숫자형 이넘  

// 주의점
이넘 값에 다른 이넘 타입의 값을 사용하면 선언하는 이넘의 첫번째 값을 초기화 해야 함. 

// 리버스 매핑
에넘의 키(key)로 값(value)를 얻을 수 있고 값(value)로 키(key)를 얻을 수도 있음

 

  • 문자형 이넘

// 이넘 값 전부 특정 문자 또는 다른 이넘 값으로 초기화 필요, 숫자형과 다르게 auto-incrementing이 없음.

 

  • 복합이넘 : 문자와 숫자를 혼합, 권고하지 않음.

연산자를 이용한 타입정의 

  • Union type : A이거나 B이다
function logText(text: string | number) {
  // ...
}

// 장점
TS의 이점을 살리면서 코딩할 수 있음
  • Intersection type : 여러 타입을 모두 만족하는 하나의 타입,  & 연산자를 이용해 여러 개의 타입 정의를 하나로 합치는 방식을 인터섹션 타입 정의 방식

클래스

  • readonly : 클래스 속성에 readonly 키워드를 사용하면 접근만 가능, 인자에 readonly 키워드를 추가해서 코드를 줄일 수 있음
  • Accessor : TS는 객체의 특정 속성의 접근과 할당에 대해 제어, 해당 객체가 클래스로 생성한 객체여야 함. get만 선언하고 set을 설정하지 않은 경우에는 자동으로 readonly로 인식 됨
  •  Abstract class : 인터페이스와 비슷한 역할을 하면서도 조금 다름, 특정 클래스의 상속 대상이 되는 클래스, 좀 더 상위레벨에서 속성/메서드의 모양을 정의 

제네릭 

  • C#, Java 등의 언어에서 재사용성이 높은 컴포넌트를 만들 때 자주 활용, 한가지 타입보다 여러 가지 타입에서 동작하는 컴포넌트를 생성하는데 사용, 타입을 마치 함수의 파라미터처럼 사용하는 것
  • 제네릭 사용 이유 : 함수의 이름 바로 뒤에 <T>/ 함수의 인자와 반환 값에 T타입 추가 > 함수를 호출 할 때 넘긴 타입에 대해 ts가 추정할 수 있게 됨 = 함수의 입력 값에 대한 타입과 출력 값에 대한 타입이 동일한지 검증 가능
  • -제네릭 타입 변수 : 위의 내용으로 사용하면 컴파일러에서 인자에 타입을 넣어달라고 경고 함. 이럴 경우, 제네릭에 타입을 줄 수 있음. T[ ]인자 삽입시 좀 더 명시적으로 타입 선언 가능  
// 제네릭에 타입주기
function logText<T>(text: T[]): T[] {
  console.log(text.length); // 제네릭 타입이 배열이기 때문에 `length`를 허용합니다.
  return text;
}

// 제네릭에 타입 선언 
function logText<T>(text: Array<T>): Array<T> {
  console.log(text.length);
  return text;
}

타입추론

  • 타입스크립트가 코드를 해석해 나가는 동작
let x = 3; x는 number로 간주
  • 가장 적절한 타입 : 몇 개의 코드를 바탕으로 타입추론, 가장 근접한 타입을 best common type이라고 함.
  • 문맥상의 타이핑 : 타이핑(타입 결정)은 코드의 위치(문맥)을 기준으로 일어남.

타입호환

  • ts코드에서 특정 타입이 다른 타입에 잘 맞는지를 의미함.
  • 구조적 타이핑 : 코드 구조 관점에서 타입이 서로 호환되는지의 여부를 판단하는 것
  • Soundness : 컴파일 시점에 타입을 추론할 수 없는 특정 타입에 대해서 일단 안전하다고 보는 특성
  • Enum 타입호환 주의사항 : number 타입과 호환 o , 이넘 타입끼리 호환 x 
  • Class 타입호환 주의사항 : 클래스 타입끼리 비교할 때 스태틱 멤버(static member)와 생성자(constructor)를 제외하고 속성만 비교
  • Generics : 제네릭 타입 간의 호환 여부를 판단할 때 타입 인자 <T>가 속성에 할당 되었는지를 기준으로 함.

타입 별칭

  • 특정 타입이나 인터페이스를 참조할 수 있는 타입 변수
  • 새로운 타입 값을 하나 생성하는 것이 아니라 정의한 타입에 대해 나중에 쉽게 참고할 수 있게 이름을 부여하는 것
  • type : 확장 x / interface : 확장 o

Usage

모듈

  • ES6 + Modules의 개념과 유사
  • 전역 변수와 구분되는 자체 유효 범위를 가짐, export / import와 같은 키워드를 사용하지 않으면 다른 파일에서 접근할 수 없음.

d.ts 파일

  • 타입스크립트 코드의 타입 추론을 돕는 파일

인덱싱

  • 타입스크립트에서 배열 요소와 객체의 속성을 접근할 때는 인터페이스를 사용

유틸리티 타입

  • 이미 정의해 놓은 타입을 변환할 때 사용하기 좋은 타입 문법
  • partial : 특정 타입의 부분 집합을 만족하는 타입을 정의
  • pick : 특정 타입에서 몇 개의 속성을 선택(pick)하여 타입을 정의
  • omit : 특정 타입에서 지정된 속성만 제거한 타입을 정의

맵드 타입

  • 기존에 정의되어 있는 타입을 새로운 타입으로 변환
  • js map() API 함수를 타입에 적용한 것과 같은 효과

Config

tsconfig

  • ts를 js로 변홀할 때의 설정을 정의해놓는 파일
  • tsc 명령어 입력시 ts파일에 정의된 내용을 기준으로 변환 작업(컴파일) 진행
// tsc 명령어
tsc app.ts

// 대상 파일을 지정하지 않으면 현재 폴더를 기준으로 변환

// 명시적으로 지정하는 명령어
# 형식 예시
tsc --project 상대 경로

 

ts 설정 파일 속성

  • files : 설정 파일에 미리 정의
  • include : 개별로 지정하지 않고,  변환할 폴더를 지정
  • exclude : 속성을 변환하지 않을 폴더 지정 (<> include)
  • types 라이브러리와 typeroots
└─ node_modules
   ├─ @types => 컴파일에 포함
   ├─ lodash => 컴파일에서 제외
  • extends : 다른 ts 설정의 내용을 가져와서 추가함
  • target : ts를 컴파일 했을 때 빌드 디렉토리에 생성되는 자바스크립트의 버전
  • lib : ts 파일을 js로 컴파일 할 때 포함될 라이브러리의 목록
  • allowjs : ts 컴파일 작업을 진행할 때 js파일도 포함할 수 있는지 설정
  • @types라이브러리 : 써브 파티 라이브러리의 타입 추론을 위해 설치하는 라이브러리, index.d.ts 파일과 package.json 파일로 구성

ETC

타입

  • 타입 별칭 type sn = number | string;
  • 인터페이스 interface I { x: number[]; }
  • 클래스 class C { }
  • 이넘 enum E { A, B, C }
  • 타입을 가리키는 import 구문

JS에 TS 적용하기

주의할 점

  • 기능적인 변경은 절대 하지 않을 것
  • 테스트 커버리지가 낮을 땐 함부로 타입스크립트를 적용하지 않을 것
  • 처음부터 타입을 엄격하게 적용하지 않을 것 (점진적으로 strict 레벨을 증가)

 

참고 사이트 : TS 핸드북