on
25 (1/2) :: Type Guard, Optional Chaining, 함수 오버로딩, 인덱스...
25 (1/2) :: Type Guard, Optional Chaining, 함수 오버로딩, 인덱스...
728x90
엘리스 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)
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 = (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 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
from http://forgottenknowledge.tistory.com/201 by ccl(A) rewrite - 2021-11-27 12:01:32