reactjs - Storybook:如何標註通用參數/屬性類型
上下文與程式碼
我們這樣擴展了按鈕:
export type ButtonProps<P = Record<string, unknown>> = P & {
children: ReactNode | string
onClick?: () => void
className?: string
disabled?: boolean
secondary?: boolean
}
const Button = <P extends Record<string, unknown>>({
children,
onClick,
className,
disabled = false,
secondary = false,
}: ButtonProps<P>) => {
...
}
這種重載意味著我們可以使用額外的屬性實現新的按鈕,而不會弄亂原本的按鈕,例如:
const FooterTwoButtons = ({
secondaryOnClick,
secondaryIconType,
icon,
className,
...props
}: ButtonProps<TwoButtonsProps>) => {
return (
<div className={clsx('grid grid-cols-5', className)}>
<Button onClick={secondaryOnClick} secondary>
{(secondaryIconType !== undefined && (
<Icon type={secondaryIconType} />
)) ||
(icon !== undefined && icon)}
</Button>
<FooterButton {...props}>{props.children}</FooterButton>
</div>
)
}
這非常好,因為它允許更多短暫的按鈕組件從我們的基礎類型擴展。一切都能編譯並按預期運作,除了 storybook...
問題
我似乎找不到任何關於現代故事書組件允許通用屬性的問題/疑問。
ExtendedButtonProps 故事:
export const ButtonExtendedProps: ComponentStory<typeof Button> = ({
secondaryIconType,
children,
...props
}: ButtonProps<ExtendedProps>) => {
return (
<div>
<Button secondaryIconType={secondaryIconType} {...props}>
{children}
</Button>
</div>
)
}
ButtonExtendedProps.args = {
...Default.args,
secondaryIconType: 'CircledX',
}
這裡是 tsc 編譯器錯誤,出現在上述代碼中的 ButtonExtendedProps:
module ButtonExtendedProps
const ButtonExtendedProps: ComponentStory<(<P extends Record<string, unknown>>({ children, onClick, className, disabled, secondary, }: ButtonProps<P>) => JSX.Element)>
Type '{ ({ secondaryIconType, children, ...props }: ButtonProps<ExtendedProps>): JSX.Element; args: Partial<Record<string, unknown> & { children: ReactNode; onClick?: (() => void) | undefined; className?: string | undefined; disabled?: boolean | undefined; secondary?: boolean | undefined; }> | undefined; }' is not assignable to type 'ComponentStory<(<P extends Record<string, unknown>>({ children, onClick, className, disabled, secondary, }: ButtonProps<P>) => Element)>'.
Type '{ ({ secondaryIconType, children, ...props }: ButtonProps<ExtendedProps>): JSX.Element; args: Partial<Record<string, unknown> & { children: ReactNode; onClick?: (() => void) | undefined; className?: string | undefined; disabled?: boolean | undefined; secondary?: boolean | undefined; }> | undefined; }' is not assignable to type 'ArgsStoryFn<ReactFramework, Record<string, unknown> & { children: ReactNode; onClick?: (() => void) | undefined; className?: string | undefined; disabled?: boolean | undefined; secondary?: boolean | undefined; }>'.
Types of parameters '__0' and 'args' are incompatible.
Type 'Record<string, unknown> & { children: ReactNode; onClick?: (() => void) | undefined; className?: string | undefined; disabled?: boolean | undefined; secondary?: boolean | undefined; }' is not assignable to type 'ButtonProps<ExtendedProps>'.
Property 'secondaryIconType' is missing in type 'Record<string, unknown> & { children: ReactNode; onClick?: (() => void) | undefined; className?: string | undefined; disabled?: boolean | undefined; secondary?: boolean | undefined; }' but required in type 'ExtendedProps'.ts(2322)
有人能看出我在這裡漏了什麼嗎?故事書文件中有提供這個的範例頁面嗎?我今天四處翻找過,但不確定該搜尋哪些關鍵字。任何建議都非常感謝。謝謝。
答案#1
碰巧的是,ComponentStory<typeof Button> === Story<ButtonProps>
所以最終的故事簽名看起來像這樣:
export const ButtonExtendedProps: Story<ButtonProps<ExtendedProps>> = ({
altIconType,
altClassName,
altAriaLabel,
children,
clean,
...props
}: ButtonProps<ExtendedProps>) => {
