Ts 를 공부하면서 느낀 점으로는 굉장히 '엄격'하다 였다. 그로인해 메서드를 만들어줄때도 타입을 일일히 지정을 해주고, 반환 값에 대한 타입도 명시해주는 일을 하다보니 무언가 비효율 적이란 생각도 들게 되었었다.
나는 특정 데이터를 받아 Null 값을 체크하는 메서드를 만들고 싶었다. 그럼 그 값이 string 일때, number 일때, boolean 일때 메서드를 일일히 다 만들어 줘야 하는걸까? 아니면 💩 과도 같은 any 타입을 지정해서 처리를 하면 될까?
이때 나온 해결책이 바로 Generic 이다. 타입 스크립트 특유의 엄격함을 유연하게 관리하게 해줄 녀석이다.
function checkNullString( data : string ) : string {
if ( data === undefined || data === null ){
throw new Error ('정의 되지 않은 문자열입니다.');
}
return data;
};
function checkNullNumber( data : number ) : number {
if ( data === undefined || data === null ){
throw new Error ('정의 되지 않은 숫자입니다.');
}
return data;
};
function checkNull( data : any ) : any {
if ( data === undefined || data === null ){
throw new Error ('정의 되지 않은 데이터입니다.');
}
return data;
};
앞서 말한것과 같이 받아오는 파라미터의 타입도 정해져 있고 반환에 대한 타입도 정해져있으면 물론 좋다. 그렇다고 예시처럼 모든 타입에 대한 체크를 위한 메서드를 일일히 만들어 줄것인가? 위 메서드를 한방에 정리하는 예시를 보자.
function checkNull <T> ( data : T ) : T {
if ( data === undefined || data === null ){
throw new Error ('정의 되지 않은 데이터입니다.');
}
return data;
};
보통 Generic 에선 받아오는 데이터에 대해 class 처럼 첫 시작 글자는 대문자로 받아온다. Type의 앞글자를 따서 T 라고 명했으며,
풀네임을 적기보다는 첫글자 만을 적는게 인지하기에도 좋다.
예시를 보게되면 이 함수에 들어오게 될 데이터는 무엇이든 될수있다. T로 받아오고, 받아올 인자의 타입또한 같은 T 여야 하며 반환값 또한 T로 반환되어져야 하는것을 볼 수 있다.
'string' 이 들어오든, 'number'가 들어오든 모두 한번에 처리가 가능해진것.
여기서 한발 더 나아가서 우리는 타입스크립트의 꽃, Type Alias 를 사용할 수가 있다.
내가 원하는 타입을 만들어서 그 타입의 값을 상속받은 개체들만 파라미터로 받는다던가, 혹은 그 타입의 값을 지닌 개체들만 받는다던가 라는 선택지를 줄수가 있다.
type Person = {
[key : string] : string | number; // Index Signature
name : string;
age : number;
};
const student : Person = {
name : 'Noah',
age : 32,
major : 'Computer Science'
};
const employee : Person = {
name : 'Jane',
age : 28,
company : 'Apple'
};
student 또한 사람이기에 이름과 나이가 존재하고, employee 또한 같은 조건이다. 다만 각각 가지는 데이터가 추가되어져 있지만, 둘다 기본적으로 Person의 타입을 받고, 확장되어진 상태인것을 알수 있는데, 그럼 이 생성된 개체들만 받아서 값을 출력하는 함수를 만들어보자
function printPersonInfo <T extends Person> ( data : T ) : void {
Object.keys(data).forEach( key => {
console.log( `${key} : ${data[key]}` );
});
};
먼저 위에 정의된 Person 의 타입을 살펴보게되면 Index Signature 이란 것이 있는데 관련 내용은 다른 포스트에서 다루도록 하겠다.
간략하게만 설명하자면 내가 data 라는 객체에 접근을 할때 주어지는 값의 타입에 대해서 정의하고 그 값에 해당하는 반환 값의 타입이 무엇인지 알려주는 것이다.
함수를 살펴보게되면 제네릭의 표현식 <> 안에 들어오는 T , 즉 함수에서 사용될 T는 Person을 상속받은 개체만 들어올 수 있다는 것을 의미하게 되는것이고 파라미터에 들어오는 data 역시 T로 받아오는것을 볼수있다.
이를통해 좀더 유연하면서도 때때론 내가 원하는 타입의 값만 받아올수있게 제약조건을 걸수도 있다는것을 알게되었다.
'회고 > TIL' 카테고리의 다른 글
Redis - cache (0) | 2023.08.19 |
---|---|
Sequelize - Scope (0) | 2023.08.02 |
2023 - 07 - 05 TIL (0) | 2023.07.05 |
2023 - 07 - 04 TIL (0) | 2023.07.04 |
2023-06-20 TIL (0) | 2023.06.20 |