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