선택이 아닌 필수, 타입스크립트
1.7.1 타입스크립트란?
타입스크립트
ㄴ기존 자바스크립트 문법에 타입을 가미한 것.
자바스크립트는 기본적으로 동적 타입의 언어이기때문에 대부분의 에러를 코드를 실행했을 때만 확인할 수 있다는 문제점이 있다.
typeof를 적용하여 문제점을 방지할 수 있지만 너무 번거롭고 코드의 크기를 과도하게 키우게 된다.
타입스크립트는 이러한 자바스크립트의 한계를 벗어나 타입 체크를 정적으로 런타임이 아닌 빌드 타임에 수행할 수 있게 해준다.
1.7.2 리액트 코드를 효과적으로 작성하기 위한 타입스크립트 활용법
any 대신 unknown을 사용하자
any는 불가피할 때만 사용해야하는 타입.
타입을 any로 설정하면 타입스크립트가 에러를 발생시키지 않는다고 하더라도 실행 시 에러가 발생할 것이다.
이는 타입스크립트를 사용하는 이점을 모두 없애버린다.
불가피하게 아직 타입을 단정할 수 없는 경우에는 unknown을 사용하자!
unknown은 어떠한 값도 할당할 수 있지만 any와는 다르게 이 값을 바로 사용하는 것은 불가능하다.
unknwon은 예상치 못한 타입을 받아들일 수 있음은 물론, 사용하는 쪽에서도 안전하게 쓸 수 있다.
타입 가드를 적극 활용하자
타입을 사용하는 쪽에서는 최대한 타입을 좁히는 것이 좋다.
타입을 좁히는 데 도움을 주는 것이 바로 타입 가드다.
조건문과 함께 타입 가드를 사용하면 타입을 효과적으로 좁힐 수 있어 더 명확하게 변수나 함수를 사용할 수 있다.
instanceof : 지정한 인스턴스가 특정 클래스의 인스턴스인지 확인할 수 있는 연산자.
typeof : 특정 요소에 대해 자료형을 확인하는데 사용하는 연산자.
in : property in object로 사용되며, 주로 어떤 객체에 키가 존재하는지 확인하는 용도로 사용된다.
제네릭
- 함수나 클래스 내부에서 단일 타입이 아닌 다양한 타입에 대응할 수 있도록 도와주는 도구.
- 타입만 다른 비슷한 작업을 하는 컴포넌트를 단일 제네릭 컴포넌트로 선언해 간결하게 작성할 수 있다.
- > 사용할 때 필요한 타입을 지정할 수 있다.
function identity<T>(arg: T): T {
return arg;
}
// 호출 시 타입을 지정
let output1 = identity<string>("Hello");
let output2 = identity<number>(42);
리액트에서 제네릭을 사용할 수 있는 코드로 useState를 떠올릴 수 있다.
function Component() {
//state: string
const [state, setState] = useState<string>('')
//...
}
useState에 제네릭으로 타입을 선언하면 state 사용과 기본값 선언을 좀 더 명확하게 할 수 있다.
제네릭으로 기본값을 선언해준다면 타입스크립트가 문제를 방지해줄 수 있다.
인덱스 시그니처
- 객체의 키를 정의하는 방식.
type Hello = {
[key: string]: string
}
const hello: Hello = {
hello: 'hello',
hi: 'hi',
}
hello['hi'] // hi
hello['안녕'] // undefined
[key: string]을 사용한 부분이 바로 인덱스 시그니처다.
인덱스 시그니처를 사용하면 이처럼 키에 원하는 타입을 부여할 수 있다.
그러나 객체의 키는 동적으로 선언되는 경우를 최대한 지양해야 하고, 객테의 타입도 필요에 따라 좁혀야 한다.
// record를 사용
type Hello = Record<'hello' | 'hi', string>
const hello: Hello = {
hello: 'hello',
hi: 'hi',
}
// 타입을 사용한 인덱스 시그니처
type Hello = { [key in 'hello' | 'hi']: string }
const hello: Hello = {
hello: 'hello',
hi: 'hi',
}
Record<key, Value>를 사용하면 객체의 타입에 각각 원하는 키와 값을 넣을 수 있다.
이렇게 객체를 원하는 형태로 최대한 좁힐 수 있다.