Type Script의 Type Checker는 타입 추론이라는 기능을 가지고 있어서, 사용자가 직접 타입을 입력하지 않아도 알아서 타입을 체크한다.
// 이렇게 쓰지 말자
let letNum1: number = 11;
const constNum1: number = 33;
// 직접 타입 작성을 하지 않아도, 알아서 추론해준다.
let letNum2 = 11; // number type
const constNum2 = 33; // Union type(33)
심지어 복잡한 객체 구조까지 추론이 가능하다.
// 아래 두 코드는 동일하게 타입이 추론된다.
// 너무 안타깝다
const person1: {
name: string;
born: {
when: Date;
where: string;
},
age: number;
} = {
name: 'Conative',
born: {
when: new Date('1997-05-13'),
where: 'Pyoung Taek'
},
age: 25
}
// 편안
const person2 = {
name: 'Conative',
born: {
when: new Date('1997-05-13'),
where: 'Pyoung Taek'
},
age: 25
}
이상적인 코드 작성법
'Effective Typescript' 책에서는 아래와 같이 말하고 있다.
함수 / 매서드 시그니처에 타입 구문을 포함하지만,
함수 내에서 생성된 지역 변수에는 타입 구문을 넣지 않는것.
이것이 이상적인 코드다.
interface Person {
name: string,
age: number
}
// 반환 값이 무엇인지 추론하게끔 하기.
const myFunc = (user: Person) => {
return user.name; // string 타입으로 추론된다.
}
타입 명시가 좋은 경우 (객체)
근데 예외로, 타입 명시가 좋은 경우도 있다.
interface Person {
name: string,
age: number
}
const setPerson(user: Person) {
const {id, age} = user;
...
}
// name에 string 타입 대신 number을 넣어보았다.
const user1 = {
name: 11,
age: 25
}
setPerson(user1); // Error, 함수 선언부에서 문제 발생하여 무슨 문젠지 한번에 알기 힘듬
//
const user2: Person = {
name: 33, // Error, 선언 당시 에러 발생하여 보기 쉬움
age: 27
}
타입 명시가 좋은 경우 (함수)
함수에서도 마찬가지다. 반환값을 지정해놓고, 예기치 못한 상황을 막아준다.
// is_load가 true면 fetch하고 싶을 때
// 이 경우, getServerData.then 등 promise 함수를 호출할 시 에러가 난다. (함수 내에선 에러없음)
const getServerData1 = (is_load: boolean) => {
if(!is_load){
return 'is_load 값이 False입니다.';
}
return fetch('/my/server');
}
// 아래와 같이 반환값 설정 시 에러가 제대로 뜬다.
const getServerData2 = (is_load: boolean): Promise<Response> => {
if(!is_load){
return 'is_load 값이 False입니다.'; // Error 발생!
}
return fetch('/my/server');
}
그리고, 반환 값을 명시해주면 타입 체커가 이상하게 추론한 것을 명확하게 적용할 수 있다.
interface Location {
x: number,
y: number
}
// getLocation1의 반환 타입은 {x:number, y:number} 으로 추론된다.
const getLocation1 = (loc1: Location, loc2: Location) {
return {
x: loc1.x + loc2;x,
y: loc1.y + loc2.y
}
}
// 반면, 반환값을 명확하게 작성하면 Location 타입으로 추론된다.
const getLocation1 = (loc1: Location, loc2: Location): Location {
return {
x: loc1.x + loc2;x,
y: loc1.y + loc2.y
}
}