react, react-native with typescript 적용해보는 팁
저는 typescript 딱 실무3개월, 공부까지 합치면 7개월 써봤습니다.
노하우와 느낀점을 적어보겠습니다.
잘못됐거나 더 좋은게 있다면 알려주세요.
Overview
1. 타입스크립트는 적용하기 어렵다 (라고 느꼈었으나 지금은 아님..!)
2. 타입스크립트를 react, react-native에 쉽게 적용하는 방법
예제는, '버튼' 컴포넌트를 만들어보는걸로 할게요.
1. 타입스크립트는 적용하기 어렵다?
export interface BasicButtonProp {
onClick: any;
}
function BasicButton({onClick}: BasicButtonProp) {
return (
<button onClick={onClick}>
버튼
</button>
);
}
처음에 버튼을 만들려고했는데.. onClick의 타입을 정해주고싶었는데..
뭐라고 정해줘야할지 막막했던적이 정말많았어요.
(꼭 버튼이 아니더라도 여기에 타입 뭐라고 적어야하지? 한적 많았어요)
"react onClick with typescript" 부터 시작해서 검색 몇십분씩 해도 못찾고 그랬죠
공식문서 예제를보면 다 기본이 자바스크립트로 나와있었어요.
타입스크립트로 어떻게 쓰는지 알려주는 공식문서도 있었고 아닌곳도 있었어요.
2. react, react-native에 쉽게 적용하는 방법
제가 좀더 간단한방법을 소개시켜드릴게요.
버튼에 커서 두고 jump to source해서 원본소스좀 살펴보고,
원하는 속성에 커서 두고 jump to source해서 원본소스좀 살펴보면,
어렵지않게 타입을 어떻게 선언해야하는지 알 수 있어요.
꼭 버튼뿐만이 아니에요.
const AppStack = createStackNavigator();
뭐 제네릭도 없고 뭐 저 함수 어떻게 쓰는거지? 모르겠으면,
(1) 공식문서에 with typescript에 해당하는 문서가 있는지 찾아보고,
(2) 없으면 원보소스 보고 타입을 어떻게 줘야하는지 익히면 되요.
버튼 예제를 마저 완성해볼게요.
react 공식문서에는 버튼의 onClick을 뭐라고쓰면 좋은지의 내용이 없기 때문에..
직접 원본소스좀 보다보면,
export interface BasicButtonProp {
onClick?: MouseEventHandler<HTMLButtonElement>;
}
어렵지않게 onClick의 타입은 저렇게 해야한다는 결론에 도달할 수 있어요.
방법은 한가지가 더 있어요.
export interface BasicButtonProp extends Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {
}
바로 Typescript의 훌륭한 기능중의 하나인 Pick이에요.
Pick은, 원하는 속성의 타입만 가져오는거에요.
export interface HtmlButtonProps {
onClick?: MouseEventHandler<HtmlButtonProps>;
children?: ReactNode;
}
export interface BasicButtonProp extends Pick<HtmlButtonProps, 'onClick'> {
}
마치 이런느낌이에요.
Button의 속성의 타입들이 선언된 HtmlButtonProps에서 onClick의 타입만 가져온거죠.
그래서 굳이 BasicButtonProp에 onClick에 대한 속성을 명시하지않아도 되요. extends했으니까요..!
이 방법의 장점은, onClick의 타입이 정확히 어떤건지 몰라도 된다는거에요.
그리고 경우에 따라 더 직관적일 수 있어요.
'원래 button의 prop의 onClick타입' 이라는 느낌이 빡 오니까요.
저는 저보다 타입스크립트 잘하는 사람 실무에서 아직 본적이 없기 때문에.......... (ㅠㅠ)
아래의 기준으로 위 두가지 방법을 적용하고있습니다.
기준 : 더 직관적인 경우
예를들어볼게요.
extends Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {
이 경우는 너무 길고 복잡해보이는거같아요.
저라면 이 경우에서는
onClick?: MouseEventHandler<HtmlButtonProps>;그냥 이렇게 직접 선언할래요.
하지만,
export interface BasicTextProp extends Pick<TextProps, 'style'> {
}
export default function BasicText({style}: BasicTextProp) {
return (
<Text style={style}>텍스트</Text>
);
}
react-native의 Text컴포넌트를 확장한 컴포넌트를 만든다고 한다면, (마치 html의 span같은 것)
저는 Pick으로 사용하겠습니다. 저게 더 직관적으로 보이는거같아요.
물론, 직접 타입을 선언한다면,
style?: StyleProp<TextStyle>;아까 설명드린대로 jump to source해서 좀 따라가면,
저 경우에 이렇게 해야한다는걸 어렵지않게 찾을 수 있을거에요.
* 주의
실제로 버튼이나 텍스트 컴포넌트를 확장한 컴포넌트를 제작하신다면,
위 예제는 적절하지 않을 수 있습니다.
위 예제는 타입을 쉽게 선언하기위한 예제일 뿐입니다.