개발팀에 속해서 일하는 동안 거의 모든 프로젝트에서 Typescript
를 사용해왔다.
하지만 프로젝트를 만드는 데에만 집중을 하고, 효율적인 언어 사용에는 관심이 많이 부족했다.
더 나은 개발과, 앞으로는 잘 사용할 거라는 다짐을 위해 유용한 팁들을 정리해보려 한다.
최대한 any
를 사용하지 않으려 노력하겠지만, 혹시나 사용할 상황이 생긴다면 Unknown
으로 대체할 수 있다.
Unknown
타입은 any
와 같이 모든 타입을 허용한다.
하지만 any
를 사용했을 때 지나치는 부분을 컴파일러에서 체크한다.
따라서 예상하지 못한 문제를 사전에 알 수가 있다.
let unknownValue: unknown;
let anyValue: any;
let unknownValue2: unknown = unknownValue; // This is fine
let anyValue2: any = unknownValue; // This is fine
let booleanValue: boolean = unknownValue; // Type 'unknown' is not assignable to type 'boolean'.
let booleanValue2: boolean = anyValue; // While this works
let numberValue: number = unknownValue; // Type 'unknown' is not assignable to type 'number'.
let numberValue2: number = anyValue; // While this works
let stringValue: string = unknownValue; // Type 'unknown' is not assignable to type 'string'.
let stringValue2: string = anyValue; // While this works
let objectValue: object = unknownValue; // Type 'unknown' is not assignable to type 'object'.
let objectValue2: object = anyValue; // While this works
let arrayValue: any[] = unknownValue; // Type 'unknown' is not assignable to type 'any[]'.
let arrayValue2: any[] = anyValue; // While this works
let functionValue: Function = unknownValue; // Type 'unknown' is not assignable to type 'Function'.
let functionValue2: Function = anyValue; // While this works
위 코드와 같이 타입에러를 확인할 수 있다.
Typescript
에는 여러가지 Utility 타입이 있다.
그중에서 활용하기 쉽고 이곳저곳 자주 보이는 몇 가지만 정리해봤다.
Partial
특정 타입을 부분적으로 만족하는 타입을 정의할 수 있다.
interface Profile {
name: string;
age: number;
}
type PartialProfile = Partial<Profile>;
const partialProfile: PartialProfile = { // age 생략가능
name: "Enjoywater",
};
Required
optional로 정의된 타입에서 optional을 없애준다.
아래 사진처럼 age
의 타입이 변경된다.
Pick
정의된 타입에서 특정 타입을 선택해서 정의할 수 있다.
아래 사진처럼 name, age
만 선택된 채로 정의된다.
Omit
정의된 타입에서 특정 타입을 제외해서 정의할 수 있다.
아래 사진처럼 name, age
이 제외된 채로 정의된다.
조건문으로 타입을 좁혀서 더욱 정확하고 안전한 타입을 보장받게 된다.
typeof
피연산자의 평가 전 자료형을 나타내는 문자열을 반환한다.
function stringOrNumber(value: string | number) {
value.substring(1); // error
/*
Property 'substring' does not exist on type 'string | number'.
Property 'substring' does not exist on type 'number'.
*/
if (typeof value === "string") {
value.substring(1); // Good
}
}
instanceof
생성자의 prototype 속성이 객체의 프로토타입 체인 어딘가 존재하는지 판별한다.
class Apple {
phone = "iphone";
}
class Samsung {
phone = "zflip";
}
function appleOrSamsung(value: Apple | Samsung) {
if (value instanceof Apple) {
return '애플';
}
return `삼성`;
}
in
명시된 속성이 명시된 객체에 존재하면 true
를 반환한다.
interface Apple {
phone: "iphone";
mouse: 'magic'
}
interface Samsung {
phone: "zflip";
}
function appleOrSamsung(value: Apple | Samsung) {
if ('mouse' in value) {
return '애플';
}
return `삼성`;
}
User Defined
interface Apple {
phone: "iphone";
mouse: 'magic'
}
interface Samsung {
phone: "zflip";
}
function isApple(value: any): value is Apple {
return value.mouse !== undefined;
}
function appleOrSamsung(value: Apple | Samsung) {
if (isApple(value)) {
return '애플';
}
return `삼성`;
}