Total Typescript - generic challenge

김동하·2025년 4월 21일
1

typescript

목록 보기
19/21
post-thumbnail

제네릭 마지막 문제...

translations라는 데이터가 있다.

이 데이터는 translate 라는 함수를 통해 변환된다. translate는 무엇인가

키 인덱싱으로 translations 의 밸류를 가져오는데, 여기서 봐야할 점은 ...args로 들어오는 동적인 값을 replace로 매핑하여 반환한다.

가령, { count : "2" }를 넘기면 아래와 같이 출력해야 한다.

...args는 옵셔널하지만, ...args가 필수값인 translations 데이터도 있다.

title의 경우, 세 번째 인자가 필수값으로 필요하다. 타입을 제대로 지정하지 않으면 컴파일 에러 없이 undefiend를 뱉는다.

이 복잡해보이는 녀석의 타입을 정해보자!

스텝 바이 스텝

먼저 translations의 제네릭을 정해보자. 객체니까 Record로 해둔다.

다음은 key다. keykeyof로 방금 만든 TTranslations의 key다.

...args의 경우 key에 따라 필수인지 옵셔널인지 정해지기고, 밸류에 {} 다이나믹한 밸류가 포함되었는지 따라 다른 타입을 줘야 하기 때문에 지금 인자로 들어오는 키가 어떤 값인지 알아야 한다(마치 런타임에서처럼)

TTarget 이란 제네릭을 만들고 확인해보면

TTargetbutton의 밸류인 Click me!가 캡쳐되는 것을 확인할 수 있다.

GetParamKeys

자, 이제 infer를 사용해야 하여 string중에 {somethingKey}에 포함된 key를 찾아내야 한다.

{${infer Param}}으로 {} 안에 밸류를 infer로 지정하고, {}가 여러개 나올 수도 있으니 나머지 부분도 infer로 떼어내 재귀를 돈다.

이제 GetParamKeys를 테스트 해보면

title의 경우 name만 잘 추출이 되고

button일 경우({}가 없을 때)는 빈 값으로 잘 추출된다.

복수개일 때도 정확히 추론한다.

GetParamKeysAsUnion

GetParamKeys의 반환값은 튜플이므로 유니언으로 만들어줘야 한다.

그럼, 원래 작성중이었던 TTarget에 기본값으로 넣어준다.

...args

이제 대망의 ...args를 처리해보자. 생각보다 간단하다TTarget이 있으면 (string의 서브타입이면) Record<TTarget, string> 아니면 []이다.

...args의 타입까지 다 정해서 전체코드를 확인해보자

전체코드

이제 테스트를 해보면 args가 없어도 되는 key인 경우 never 타입으로 떨어져 에러가 발생하고

args가 있는 경우는 정삭 동작한다.

args가 있어야 하는데 없는 경우도 에러가 발생하고

자동완성까지 깔끔하게 된다.

참고 : total typescript

profile
프론트엔드 개발

0개의 댓글