일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- springboot
- ReactHooks
- satisfiles
- hook
- designpatterns
- component
- 오블완
- JavaSpring
- css
- React
- storybook
- go
- 웹애플리케이션서버
- golang
- react-hook-form
- Chakra
- javascript
- backend
- typescript
- frontend
- java
- tanstackquery
- 티스토리챌린지
- Redux
- Spring
- Gin
- test
- JPA
- RTK
- Today
- Total
bkdragon's log
1장 타입스크립트 알아보기 본문
타입스크립트와 자바스크립트의 관계 이해하기
타입스크립트는 문법적으로 자바스크립트의 상위집합이다. 자바스크립트 프로그램에 문법 오류가 없다면, 유효한 타입스크립트 프로그램이다. 이 특성은 자바스크립트 코드를 타입스크립트로 마이그레이션하는 데 엄청난 이점이 된다. 모든 자바스크립트 프로그램은 타입스크립트 프로그램이지만 그 반대는 아니다.
타입스크립트의 타입 시스템의 주된 목표는 런타임에 오류를 발생시킬 코드를 미리 찾아내는 것이다. 타입스크립트를 정적 타입 시스템이라하고 하는 것이 바로 이 특징을 말하는 것이다.
타입스크립트는 자바스크립트의 런타임 동작을 모델링한다.
const x = 2 + "3";
const y = "2" + 3;
위 코드는 타입스크립트에서 오류를 발생하지 않는다.
타입스크립트 설정 이해하기
타입스크립트 설정은 tsconfig.json 파일에서 할 수 있다. any를 허용하지 않는 noImplicitAny, 모든 타입에서 null 또는 undefined를 허용하는 strinctNullChecks. 이 두가지가 대표적인 설정이다. 두 설정 모두 켜서 사용하는게 타입 안정성을 가장 높힐 수 있다.
되도록이면 noImplicitAny 는 true 로 설정하는 것이 좋다. 다만, 자바스크립트 프로젝트를 타입스크립트로 마이그레이션 할 때는 false 로 설정하는 것이 훨씬 수월하다.
코드 생성과 타입이 관계없음을 이해하기
타입스크립트가 자바스크립트로 변환될 때 코드 내의 타입과 실행 시점에서의 타입에는 영향을 미치지 않는다.
이로 인해 아래와 같은 특성을 가진다.
- 타입 오류가 있는 코드도 컴파일이 가능하다. (noEmitOnError 로 막을 순 있다.)
- 런타임에 타입 체크가 불가능하다.
interface Squere {
}
interface Rectangle extends Squere {}
type Shape = Squere | Rectangle
function calculateArea(shape: Shape) {
if(shape instanceof Retangle) {
}
}
위 코드는 타입을 값을 사용하고 있다는 에러가 발생한다. 타입 체크를 하고 싶다면 in 키워드로 속성을 확인하거나 태그를 기입하는 방법이 있다.
interface A {
tag : "A"
}
interface B {
tag : "B"
}
- 타입 연산은 런타임에 영향을 주지 않는다. (ex.as 문이 타입을 변경하거나 하지 않는다.)
- 런타임 타입은 선언된 타입과 다를 수 있다.
- 타입스크립트 타입으로는 함수를 오버로드할 수 없다.
- 타입스크립트 타입은 런타임 성능에 영향을 주지 않는다.
구조적 타이핑 익숙해지기
자바스크립트는 덕 타이핑 기반이다. 타입스크립트는 이를 모델링하기 위해 구조적 타이핑을 사용한다.
interface Vector2D {
x: number;
y: number;
}
interface Vector3D {
x: number;
y: number;
z: number;
}
const calculate = (v: Vector2D) => {
return Math.sqrt(v.x * v.x + v.y * v.y);
};
const normalize = (v: Vector3D) => {
const length = calculate(v);
return {
x: v.x / length,
y: v.y / length,
z: v.z / length,
};
};
normalize({ x: 3, y: 4, z: 5 });
위 코드는 구조적 타이핑으로 인한 오류가 있다. Vector3D 는 Vector2D가 될 수 있기 때문에 calculate의 인자로 사용이 가능하지만 z 속성이 무시된다.
클래스 역시 구조적 타이핑의 규칙을 따른다.
class C {
foo: string;
constructor(foo: string) {
this.foo = foo;
}
}
const c = new C("foo");
const d: C = {
foo: "bar",
};
위 코드는 에러가 발생하지 않는다.
any 타입 지양하기
any 타입은 위험하다.
- any 타입에는 타입 안전성이 없다. (타입 체크가 동작하지 않는다.)
- any 타입은 함수 시그니처를 무시한다. (any 타입 변수가 함수의 매개변수 타입을 무시하고 들어간다.)
- any 타입에는 언어 서비스가 적용되지 않는다. (자동완성, 도움말이 제공되지 않는다.)
- any 타입은 설계를 감춘다.
- any 타입은 타입시스템의 신뢰도를 떨어뜨린다.