타입스크립트

Date
Created
Apr 28, 2024 07:07 AM
Tags
1장

타입스크립트란?

자바스크립트 문법에 타입을 가미한 것.
자바스크립트는 기본적으로 동적 타입 언어이지만 정적 타입을 검사할 수 있도록 해준다.
어디까지나 타입스크립트는 자바스크립트의 슈퍼셋일 뿐 자바스크립트에서 불가능한 일은 타입 스크립트에서도 안된다.
타입스크립트 파일은 결국 자바스크립트로 변환되어 Node나 브라우저 같은 자바스크립트 런타임 환경에서 돌아가는것이 목표이기 때문에 타입스크립트는 결국 자바스크립트로 변환이 된다.

리액트에서 타입스크립트 활용법

any 대신 unknown을 사용하자

타입 스크립트를 사용할 때 실수 . 중하나는 any를 자주 사용하는 것.
any는 정말 불가피한 경우에만 사용해야 하고 any를 사용하는건 타입스크립트가 제공하는 정적 타이핑의 이점을 모두 버리는것.
불가피하게 타입을 단정할 수 없는 경우 unknown을 사용하는 것이 좋다. unknown도 모든 값을 할당 할 수 있지만 any와 다르게 바로 사용할 수 없다.
function a (callback: unknown){ callback() //error }
unknown은 아직 알 수 없는 값이기에 사용할 수 없다는 에러.
unknown으로 선언된 변수를 사용하려면 type narrowing 타입 단언을 해줘야 한다.
function a (callback: unknown){ if(typeof callback === 'function'){ callback() } }
unknown이 원하는 타입인 경우에만 의도대로 작동하도록 수정되었고 이렇게 사용하는건 예상치 못한 타입을 받아들일 수 있음은 물론 사용하는 쪽에서도 안전하게 사용이 가능.

never

unknown과 반대로 never이 있는데 unknown과 반대로 어떤 타입도 들어올 수 없음을 의미함.
type a = string & number
이런 말도안되는 코드상에 존재가 불가능한 타입을 never로 사용됨
이런 never는 타입스크립트로 클래스 컴포넌트를 선언할 때 props는 없지만 state가 존재하는 상황해서 빈 props, 정확히는 어떤 props도 받아들이지 않는다는 뜻으로 사용이 가능함.

타입 가드를 적극 활용하자

타입을 사용하는 쪽에서는 최대한 타입을 좁히는 것이 좋다.
이런 타입을 좁히는데 도움을 주는 것이 타입 가드.

instannceof와 typeof

instannceof는 지정한 인스턴스가 특정 클래스의 인스턴스인지 확인할 수 있음.
class UnAuthError extends Error{ constructor(){ super() } ... } class UnExpectedError extends Error{ constructor(){ super() } } async function fetchSomthing(){ try{ const res = await fetch('...') return await res.json() }catch(e){ if( e instanceof UnAuthError){ ... } if( e instanceof UnExpectedError){ ... } throw e } }
unknown으로 내려오는 에러를 타입 가드를 통해 타입을 좁혀 각 에러에 따라 원하는 처리 내용을 추가할 수 있음.
typeof 연산자는 앞서 예제에서 볼 수 있었던 것 처럼 특정 요소에 대해 자료형을 확인하는 데 사용됨.
function loggin(value: string | undefined) { if( typeof value === 'string') console.log(value) } if( typeof value === 'undefined'){ return } }

in

in은 주로 객체에 특정한 키가 존재하는지 확인하는 용도로 사용됨.
interface Student { age: number score: number } interface Teacher { name: string } function a(person: Student | Teacher){ if('age' in person){ person.age person.score } if('name' in person){ person.name } }
person은 Student나 Teacher가 될 수 있는데 in을 활용해 특정 객체에만 있는 프로퍼티로 값을 확인하고 조건문으로 좁혔다.
겹치지 않는 프로퍼티 값으로 어떤 타입에서 내려왔는지 확인하는 것.

제네릭

제네릭은 함수나 클래스 내부에서 단일 타입이 아닌 다양한 타입에 대응할 수 있도록 도와주는 도구.
가장 쉽게 볼 수 있는 부분은 useState<string>(’’)의 형태
제네릭을 1개 이상 사용이 가능한데 이런 경우에는 T, 나 U 보다는 정확한 네이밍이 좋다고 한다.

인덱스 시그니처

인덱스 시그니처는 객체의 키를 정의하는 방식
type Hello = { [key: string] : string // <- 인덱스 시그니처 } const hello: Hello = { hello: 'hello' hi: 'hi' } hello['hi'] hello['안녕'] // undefined
인덱스 시그니처를 사용하면 이처럼 키에 원하는 타입을 부여할 수 있음.
동적인 객체를 정의할 때 유용하지만 키의 범위가 string처럼 너무 넓어져 존재하지 않는 키로 접근하면 undefined로 반환될 수 있음.
객체 키는 동적으로 선언되는 경우를 최대한 지양하고, 객체의 타입도 필요에 따라 좁혀야 함.
type hello = Record<'hello' | 'hi', string> // record const hello: Hello = { hello: 'hello', hi: 'hi' } type Hello = {[key in 'hello' | 'hi'] : string} // 인덱스 시그니처 const hello: Hello = { hello: 'hello', hi: 'hi' }

타입스크립트의 특징

자바스크립트는 다른 언어에 비해 객체가 열려있는 구조로 만들어져 있어 덕 타이핑으로 객체를 비교해야 한다.
여기서 덕 타이핑이란 객체의 타입이 클래스 상속, 인터페이스 구현 등으로 결정되는 것이 아니고 어떤 객체가 필요한 변수와 메서드만 지니고 있다면 해당 타입에 속하도록 인정해 주는것.
오리처럼 소리를 내고 헤엄치고, 걸으면 무엇도 오리로 부를 수 있다.
type Car = {name: string} type True = Car & {power: number} function horn(car: Car){ console.log(car) } const truck: Truck = { name: '비싼차', power: 100 } horn(truck) // Car에 필요한 속성을 다 갖추었으니 유효하다.
이렇게 자바스크립트는 객체의 타입에 구해받지 않고 객체의 타입에 열려있으니 타입스크립트도 이러한 자바스크립트의 특징을 맞춘것.