[Typescript]: type, interface, generics 사용하기

1. type
type PeopleType = {
name: string
age: number
}
type WindowStates = "open" | "closed" | "minimized";
type LockStates = "locked" | "unlocked";
type PositiveOddNumbersUnderTen = 1 | 3 | 5 | 7 | 9;
type Dog = {
name: string;
tail?: {
shakeTail?: () => string;
};
hasMaster?: boolean;
};
function sayHi(dog: Dog): string {
return dog.tail?.shakeTail?.();
}
Type의 property를 optional하게 지정할 수 있다.
2. interface
- 주로 객체의 value 타입을 정의한다.
- 인터페이스 이름앞에 대문자로 쓴다.
- type과 다르게 선언적 확장(같은 이름으로 확장 선언)이 된다는 특징이 있다.
interface User {
name: string;
id: number;
addComment: (comment:string) => string;
}
정의한 interface의 타입을 user 에 적용한다.
const user: User = {
name: "Hayes",
id: 0,
addComment: (comment) => `This is ${comment}`
};
인터페이스 확장 예시
interface ButtonInterface {
readonly _type:string;
width?:number;
height?:number;
onInit?():void;
onClick():void;
}
// ButtonInterface를 확장하는 ToggleButtonInterface
interface ToggleButtonInterface extends ButtonInterface {
toggle():void;
onToggled?():void;
}
// ButtonInterface를 확장하는 CounterButtonInterface
interface CounterButtonInterface extends ButtonInterface {
increase():void;
decrease():void;
onIncreased?():void;
onDecreased?():void;
}
3. Generic
Generic이란 데이터의 타입을 일반화한다(generalize)한다는 것을 뜻한다. 여러 종류의 타입에 대해 호환을 맞춰야 하는 상황에서 사용하는 문법이다. Generic은 자료형을 정하지 않고 여러 타입을 사용할 수 있게 해준다. 즉, 선언 시점이 아니라 생성 시점에 타입을 명시하여 하나의 타입만이 아닌 다양한 타입을 사용할 수 있도록 하는 기법이다. 한번의 선언으로 다양한 타입에 '재사용'이 가능하다는 장점이 있다. 제네릭을 쓰지 않을 경우, 불필요한 타입 변환을 하기 때문에 프로그램의 성능에 악영향을 미치기도 하는데, 제네릭을 사용하게되면 따로 타입 변환을 할 필요가 없어서 프로그램의 성능이 향상되는 장점이 있다.
function sort<T>(items:T[]) :T[] {
return items.sort();
}
const nums :number[] = [1,2,3,4];
const chars :string[] = ["a", "b", "c", "d"];
sort<number>(nums);
sort<string>(chars);
generic을 쓰지 않는다면,
-
타입을 미리 지정하거나, 2) any를 이용하여 구현해야 한다.
-
확실한 타입체크가 이뤄질 수 있겠지만 항상 number라는 타입을 받아야하므로 범용성이 떨어진다.
-
any를 사용한다면 자료의 타입을 제한할 수 없고, 이 function을 통해 어떤 타입의 데이터가 리턴되는지 알 수 없다.

generic을 쓴다면,
1) 제네릭의 기본적인 구조

2) 배열의 형태를 받을 때

3) 두 개 이상의 Generic 사용하기

두 변수의 타입이 다를 경우 두 가지의 타입 변수가 필요할 때 사용한다. T 다음으로 오는 알파벳인 U를 사용한다.
4) 두 개 이상의 Generic 사용하기

extends와 삼항연산자를 통해 조건부 타입으로도 정의할 수 있다.
4. 코드 스타일(Props-suffix)
When using props we name props usually according to the component we’re writing, with a Props-suffix.
type GreetingProps = {
name: string;
};
function Greeting(props: GreetingProps) {
return <p>Hi {props.name} ?</p>
}
Destructuring 코드 스타일을 작업하여 가독성을 더욱 높인다.
function Greeting({ name }: GreetingProps) {
return <p>Hi {name} ?</p>;
}