엘리스 SW 엔지니어 트랙 25일차
송현지 강사님 온라인 강의날
다양한 예시 보여주셔서 감사합니다
타입 심화
Union Type
Or
A타입 이거나 B 타입
A | B
유니온 타입 예시
// Union Type
let one : string | number
one = '1'
one = 1
인터페이스는 유니온 타입 확장 불가
type과 &를 사용해줘야한다
type으로 유니온 타입 확장 예시
type A = string | number
// 이건 에러 나온다
interface StrOrNum extends A {
a: string
}
// 이렇게 바꿔줘야된다
type StrOrNum = {
a: string
} & (string | number)
Union Type은 겹치는 것만 사용가능
type Human = {
think: () => void
eat: () => void
}
type Dog = {
bark: () => void
eat: () => void
}
declare function getEliceType(): Human | Dog
const elice = getEliceType()
// 이건 가능하지만
elice.eat()
// 이게 오류가 난다는 이야기
elice.think()
elice.bark()
Intersection Type
And
A타입과 B타입이 있으면
A타입이면서 B 타입
A & B
// Intersection Type
type Human ={
think: () => void
}
type Developer ={
work: () => void
}
// Human 이면서 Developer
const elice: Human & Developer = {
think() {},
work() {}
}
Type Guard
타입스크립트가 타입을 추론할 수 있도록 단서를 주는 것 => 구별된 유니온
if문을 사용하는 방법이 있다
실무에서 구별된 유니온과 타입가드 자주 사용한다
Discriminated Union(구별된 유니온)
구별된 유니온 사용 예시
type SuccessResponse = {
status: true
data: any
}
type FailureResponse = {
status: false
error: Error
}
type CustomResponse = SuccessResponse | FailureResponse
declare function getData(): CustomResponse
const response: CustomResponse = getData()
if (response.status) {
console.log(response.data)
} else if(response.status === false){
console.log(response.error)
}
타입 가드 종류
1. instanceof 연산자
클래스도 타입인걸 이용
객체가 어떤 클래스 객체인지 구별할 때 사용
worker instanceof Designer
2. typeof 연산자
typeof 데이터 === 'string'
typeof 데이터 === 'undefined'
. . .
3. in 연산자
문자열 A in 오브젝트
'tail' in elice
4. literal type guard
- switch() { case '타입' } 이용
- if문 '타입' 이용
5. 사용자정의 함수
오픈소스 sindresorhus/is 사용해서 타입체크 가능
둘 중 하나로 설치가능
- Yarn add @sindersorhus/is
- npm install @sindersorhus/is
Optional Chaining
객체가 null 또는 undefined면 undefined 리턴
아니면 데이터 값 리턴
data?.chaining
위의 예는 data가 null이나 nudefined값이 아닐 때 chaining이 실행
예시를 하나 더 들어보면
dog?.tail?.살랑살랑?.()
// dog이 null, undefined가 아니면 tail
// tail이 null, undefined가 아니면 살랑살랑
// 살랑살랑이 null, undefined가 아니면 비로소 살랑살랑() 실행
&&와 ?. 의 차이점
- &&
falsy(false, null, undefined, '', 0, -0, Nan) - ?.
null, undefined
Optional Chaining 사용 예시
type Cat = {
sitDown?: () => void
}
function trainCat(cat: Cat) {
cat.sitDown?.()
}
post.comments?.[0]
Nullish Coalescing Operator
A??B
좌항이 null, undefined 경우에만 B 리턴
A||B
얘는 falsy 값이 전부 포함
Function Overloading(함수 오버로딩)
같은 이름의 함수를 만들고,
파라미터의 형태가 다양한 여러 케이스에 대응
타입 가드 느낌이 나네
3가지가 같아야된다
- 함수 이름
- 매개변수 순서
- 변환 타입
arrow function 오버로딩 불가능
Function Overloading 선언 예시
// Function Overloading
class User {
constructor(private id: string){}
// 함수 이름 setId,
// 매개변수 순서 id,
// 변환타입 string 같다
setId(id: string): string
setId(id: number): string
// error 예시
setId(id: string): number
setId(radix: number, id: number):string // radix가 뒤로 가야된다
}
Function Overloading 구현 예시
// Function Overloading 구현
class User {
constructor(private id: string){}
setId(id: string): void
setId(id: number, radix: number): void
// radix가 추가되서 Optional 처리
setId(id: string | number, radix?: number): void {
this.id = typeof id === 'number' ? id.toString(radix): id
}
}
제네릭 vs 함수 오버로딩
타입 추론 시점
- 제네릭: 타입이 사용 되는 시점
- 함수 오버로딩: 타입을 선언하는 시점
용도
- 제네릭: 제네릭, 인터페이스, 클래스, 함수, 메서드
- 함수 오버로딩: 함수, 메서드
어떤 타입이 올지 모르면 제네릭 사용하자!
Type Assertion
타입스크립트가 추론 못하는 타입
as 혹은 꺾쇠<> 이용해서
타입스크립트한테 알려주는것
Type Casting vs Type Assertion
- Type casting: 데이터 타입 변환
- Type assertion: 데이터 타입 명시
Type Assertion 예시
let someValue: unknown = "this is a string"
let strLength: number = (someValue as string).length
let strLength: number = (<string>someValue).length
react의 JSX에서 꺾쇠괄호<> 이녀석이 혼동되서 as가 나왔다
결국 Type Assertion을 쓰지말고
타입 선언을 사용하라는 것으로 들린다
type Duck = {
꽥꽥: () => void;
헤엄: () => void;
};
// 타입 단언(Type Assertion)
// const duck = {} as Duck;
// 타입 선언
const duck : Duck = {
꽥꽥(){
console.log("꽥꽥")
},
헤엄(){
console.log("어푸어푸")
}
}
duck.꽥꽥(); // "꽥꽥" 출력(console.log 사용)
duck.헤엄(); // "어푸어푸" 출력
Index Signature
자바스크립트의 Index Signature
객체 접근 예시
// JavaScript Index Signature
dog['name']
Index Signature는
객체의 프로퍼티 잘 모를 때 사용
타입스크립트의 Index Signature
예시
// TypeScript Index Signature
type ArrStr = {
[key: string] : string | number
[index: number]: string
length: number
}
Index Signature 문제점
타입이 인덱스 시그니처로만 되어있으면 에러가 안난다
예시
type ArrStr = {
[key: string]: string | number
[index: number]: string
}
const a: ArrStr = {}
a['str'] // 에러가 안난다
어떤 타입이 올지 알면
인덱스 시그니처 사용하지 말자
런타임에 객체의 프로퍼티 모를 때만 사용하자
이렇게도 사용한다
// index Signature
// 이렇게 사용하거나 1
// type HttpHeaders = {
// [key: string]: string
// }
// 이렇게 사용하거나 2
type HttpHeaders = Record<string, string>
const headers: HttpHeaders = {
'Host': 'elice.io' ,
'Connection': 'keep-alive' ,
'Accept': '*/*' ,
'Access-Control-Request-Method': 'GET' ,
'Access-Control-Request-Headers': 'authorization' ,
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36' ,
'Sec-Fetch-Mode': 'cors' ,
'Sec-Fetch-Site': 'same-site' ,
'Sec-Fetch-Dest': 'empty' ,
'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7' ,
}
console.log(headers['Host']) // elice.io
궁금
type vs interface
'Web Dev > ELICE' 카테고리의 다른 글
26 :: Node.js, 서버 만들기, express.js, 왜 Docker 쓰나 (0) | 2021.11.30 |
---|---|
25 (2/2) :: TypeScript 데코레이터 (0) | 2021.11.27 |
24 :: TypeScript Generic, Constraints, keyof (0) | 2021.11.26 |
23 (3/3) :: TypeScript 복습, 실습 (0) | 2021.11.25 |
23 (2/3) :: Generic (0) | 2021.11.25 |