タイプスクリプトでstyled-conents Propタイプを指定する


TLDR;

styled関数1個目は、以下のように入れます.
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... ? > // 자동 완성이 안 된다?
これは私たちの前に入っているJENNERICがTemplate Literal Tagged Functionで使用しているInterpolation FunctionタイプなのでこのタイプはThemedStyledFunctionBase.
@types/styled-componsesのThhemedStyledFunctionBase
次のコードを見てください.Tagged Functionを使用すると、
<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 타입
タイプの定義はいくつかの段階に分かれていますが、絶えず伝わるので複雑に見えますが、タイプを遡ります.
BlockPropタイプ
U型
StyledComponentタイプ
最終的に、StyledComponentBaseタイプをジュネーブに渡すのは、次のコードのうちStyledComponentPropsのジュネーブです.見えますか?JSXを使用しているとBlockPropタイプで推論されているので見えません.
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;
ではOどこから?
幸いなことに、extends React.ComponentType<any> = Cライブラリでは一致したネーミング法が使われているので、把握しやすいです.C関数の1番目の4番目の要素Cを入れればいいです.これは私たちが使っている関数です.
要するに、Propタイプを外部から正確に推定するには、以下のように書くべきです.
import styled from 'styled-components'
import Block as BaseBlock from '../Block'

const Block = styled<BlockProp>(Block)` ... `