카테고리 없음
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 레벨을 증가)