타입스크립트(TS) (3)함수, 클래스, 제네릭
함수
명시적 this
interface Whale {
name: string
age: number
}
const whale: Whale = {
name: 'cado',
age: 5
}
//명시적으로 this의 타입을 지정
function hello(this: Whale, message: string) {
console.log(`Hello ${this.name}, ${message}`)
}
hello.call(whale, 'You are awesome')
this를 명시하지 않을 경우 암묵적으로 any 타입이 설정됨 (not good . . .)
오버로딩
각 타입별로 함수를 여러 개 만들지 않고도 타입 분기 가능
function add(a: string, b: string): string //add함수의 1번째 타입 선언
function add(a: number, b: number): number //add함수의 2번째 타입 선언
function add(a: any, b: any): any {
return a + b
} //함수 구현 (타입선언X)
add('hello ', 'world') //'hello world'
add(1,2) //3
//add('hello ', 2)
//오류. a가 string이면 b도 string이어야 함
클래스
*접근 제어자(Access Modifiers)
속성, 메소드에서 사용가능
- public : 어디서나 자유롭게 접근 가능. 클래스 바디에서는 생략할 수 있음
- protected : 나와 파생된 후손 클래스 내에서 접근 가능
- private : 내 클래스에서만 접근 가능
class UserA {
//this로 접근하는 속성 부분의 타입은
//constructor함수 위쪽에 있는 body부분(중괄호 시작부터 끝까지)에
//타입 명시 필요
first: string = '' //초기화 가능
last: string = ''
age: number = 0
constructor(first: string, last: string, age: number) {
this.first = first
this.last = last
this.age = age
}
getAge() {
return `${this.first} ${this.last} is ${this.age}`
}
}
class UserA {
//매개변수 부분에서 접근제어자를 명시하는 방법 (이때 public 생략은 불가)
constructor(
public first: string,
public last: string,
public age: number
) {
}
getAge() {
return `${this.first} ${this.last} is ${this.age}`
}
}
제네릭
1) 함수
interface Obj {
x: number
}
type Arr = [number, number]
// function toArray(a: string, b: string): string[]
// function toArray(a: number, b: number): number[]
// function toArray(a: boolean, b: boolean): boolean[]
// function toArray(a: Obj, b: Obj): Obj[]
// function toArray(a: Arr, b: Arr): Arr[]
// function toArray(a: any, b: any) {
// return [a, b]
// }
//오버로딩 대신 제네릭 문법 사용
function toArray<T>(a: T, b: T) {
return [a,b]
}
console.log (
toArray('cado', 'avo'), //T는 string 타입
toArray<string>('nana', 'khill'), //T를 직접 지정하는 것도 가능
toArray(1, 2), //T는 number 타입
toArray(true, false), //T는 boolean 타입
toArray({ x: 1 }, { x: 2 }), //T는 Obj 타입
toArray([1, 2], [3, 4]) //T는 Arr 타입
toArray([1, 2], [3, 4, 5]) //T는 배열 타입 (number[]) (타입 추론)
)
2) 클래스
한 클래스를 사용할 때마다 다른 타입을 지정 가능
class User<P> {
constructor (public payload: P) {}
getPayload() {
return this.payload
}
}
interface UserAType {
name: string
age: number
isValid: boolean
}
interface UserBType {
name: string
age: number
emails: string[]
}
const cado = new User<UserAType>({ //payload 타입이 UserAType
name: 'Cado',
age: 5,
isValid: true
})
const nana = new User<UserBType>({ //payload 타입이 UserBType
name: 'Nana',
age: 4,
emails: ['abc@gmail.com']
})
3) 인터페이스
interface MyData<T> {
name: string
value: T //value의 타입 지정 가능
}
const dataA: MyData<string> = {
name: 'Data A',
value: 'Hello world' //value는 string 타입
}
const dataB: MyData<number> = {
name: 'Data B',
value: 1234 //value는 number 타입
}
+) 제약 조건(Constraints)
제네릭 타입변수에 허용할 수 있는 타입을 제한 가능
interface MyData<T extends string | number> {
name: string
value: T //value의 타입은 string 또는 number만 가능
}
const dataC: MyData<boolean> = {
name: 'Data C',
value: false //허용되지 않음
}
+) tsconfig.json
{
//컴파일러 옵션 지정
"compilerOptions": {
"target": "ES2015",
"module": "ESNext",
"moduleResolution": "Node",
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"strict": true,
},
//컴파일할 파일 경로 목록
"include": [
"src/**/*.ts"
],
//컴파일에서 제외할 파일 경로 목록
"exclude": [
"node_modules"
]
}
compilerOptions
target : 컴파일될 ES(JS) 버전 명시
module : 모듈 시스템 지정 "CommonJS"(기본값) / "AMD" / "ESNext"(ESM방식)
moduleResolution : 모듈 해석 방식 지정 "Node"(기본값, index 이름 생략 가능)
esModuleInterop : ESM 모듈 방식 호환성 활성화 여부 false(기본값)
isolatedModules : 모든 파일을 모듈로 컴파일. false(기본값) true(import/export 키워드 필수)
baseUrl : 모듈 해석에 사용할 기준 경로 지정 "./"
typeRoots: 컴파일러가 참조할 타입선언(d.ts) 경로 지정. ["./node_modules/@types"]
lib: 컴파일에서 사용할 라이브러리 지정(배열). "ESNext", "DOM"
strict : 더 엄격한 타입 검사 활성화
strict true 사용시 아래 옵션도 true로 활성화됨
- noImplicitAny : 암시적 any 타입 검사 활성화
- noImplicitThis : 암시적 this 타입 검사 활성화
- strictNullChecks : 엄격한 Nullish 타입 검사 활성화
- strictFunctionTypes : 엄격한 함수의 매개변수 타입 검사 활성화
- strictPropertyInitialization : 엄격한 클래스의 속성 초기화 검사 활성화
- strictBindCallApply : 엄격한 bind, call, apply 메소드 인수검사 활성화