타입스크립트에서 styled-components Prop 타입 지정하기
TLDR;
styled
함수 제네릭의 첫 번째로 아래처럼 넣어주면 됩니다.
const Component = styled<ComponentType<Prop>>(BaseComponent)` ... `
템플릿 리터럴 타입이 너무 복잡해!
예를들어서 아래와 같이 Block
이라는 컴포넌트를 만든다고 해봅시다.
// Block.tsx
import styled from 'styled-components'
import Block as BaseBlock from '../Block'
interface BlockProps {
size: 100 | 200 | 300;
...
}
const Block = styled(BaseBlock)<BlockProps>`
${(props) => {
props.si... // 자동 완성이 잘 된다!
}}
`
export default Block;
근데 이 컴포넌트를 사용하려고 보니까 자동 완성이 안 됩니다.
// SomeOther.tsx
import Block from './Block'
...
<Block si... ? > // 자동 완성이 안 된다?
이건 우리가 앞에서 집어 넣은 제네릭이 Template Literal Tagged Function 안에서 쓰는 Interpolation Function 타입으로만 들어가서 그렇습니다. 이 타입은 ThemedStyledFunctionBase
인데요.
@types/styled-components 의 ThemedStyledFunctionBase
아래 코드를 보시면 Tagged Function으로 사용할 때 BlockProp
을 U
라는 제네릭으로 넣어주고 있는 겁니다.
<U extends object>(
first:
| TemplateStringsArray
| CSSObject
| InterpolationFunction<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>,
...rest: Array<Interpolation<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>>
): StyledComponent<C, T, O & U, A>;
정리하자면,
const Block = styled(Block)<BlockProp>
// == ThemedStyledFunction 타입
// == ThemedStyledFunctionBase 타입
const Block = styled(Block)<BlockProp>` ... `
// == ThemedStyledFunctionBase
// == ThemedStyledFunctionBase 타입의 Tagged Function을 실행한 "리턴 값"의 타입
// == StyledComponent 타입
타입 정의가 여러 단계로 들어가 있고, 제네릭이 계속 전달되다보니 복잡해보였지만 타입들을 한번 거슬러 올라가보겠습니다.
StyledComponent
타입
StyledComponentBase
타입
StyledComponentProps
타입
결국 BlockProp
타입이 제네릭으로 전달된 곳은 아래 코드에서 O
에 해당하는 제네릭입니다. 보시면 extends React.ComponentType<any> = C
로 되어있는 거 보이시나요? 우리가 JSX로 사용할 때는 C
타입으로 추론을 하기 때문에 안 보이는 거였습니다.
export type StyledComponentProps<
// The Component from whose props are derived
C extends string | React.ComponentType<any>,
// The Theme from the current context
T extends object,
// The other props added by the template
O extends object,
// The props that are made optional by .attrs
A extends keyof any,
// The Component passed with "forwardedAs" prop
FAsC extends string | React.ComponentType<any> = C
> =
// Distribute O if O is a union type
O extends object
? WithOptionalTheme<
MakeAttrsOptional<C, O, A> & MakeAttrsOptional<FAsC, O, A>,
T
>
: never;
그럼 C
는 어디에서 오는가?
다행이도 @types/styled-components
라이브러리에서는 일관된 제네릭 이름을 사용하고 있어서 파악하기 쉬웠는데요.
ThemedStyledFunction
함수의 첫 번째 제네릭인 C
로 넣어주면 됩니다. 이건 우리가 styled
라고 사용하고 있는 함수입니다!
결론적으로 외부에서도 Prop 타입을 올바르게 추론하고 싶다면, 아래처럼 써 주어야 하는 것이죠.
import styled from 'styled-components'
import Block as BaseBlock from '../Block'
const Block = styled<BlockProp>(Block)` ... `
Author And Source
이 문제에 관하여(타입스크립트에서 styled-components Prop 타입 지정하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@luk3/타입스크립트에서-styled-components-Prop-타입-지정하기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)