reactjs - Storybook: Cum să marchezi tipurile generice pentru args/props
Context și Cod
Am extins butonul nostru astfel:
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>) => {
...
}
Această supraîncărcare înseamnă că putem implementa butoane noi cu proprietăți suplimentare, fără a deranja butonul original, ceva de genul:
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>
)
}
Este super fain deoarece permite ca mai multe componente efemere de buton să fie extinse din tipul nostru de bază. Totul se compilează și funcționează conform așteptărilor, cu excepția storybook...
Problemă
Se pare că nu pot găsi nicio întrebare/problema legată de un component modern storybook care să permită proprietăți generice.
Povestea 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',
}
Iată eroarea compilatorului tsc, care apare la ButtonExtendedProps în codul de mai sus:
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)
Poate cineva să vadă ce am ratat aici? Există o pagină în documentația Storybook care oferă exemple pentru asta? Am căutat destul de mult astăzi, dar nu sunt sigur ce cuvinte cheie să folosesc. Orice sfat este foarte apreciat. Mulțumesc.
Răspuns #1
Așa cum s-ar întâmpla, ComponentStory<typeof Button> === Story<ButtonProps>
Deci semnătura poveștii rezultate arăta astfel:
export const ButtonExtendedProps: Story<ButtonProps<ExtendedProps>> = ({
altIconType,
altClassName,
altAriaLabel,
children,
clean,
...props
}: ButtonProps<ExtendedProps>) => {
