reactjs - Storybook: Kuinka merkata geneeriset args/props-tyypit
Konteksti & Koodi
Laajensimme painikettamme näin:
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>) => {
...
}
Tämä ylikuormitus tarkoittaa, että voimme toteuttaa uusia painikkeita lisäominaisuuksilla, ilman että sotkemme alkuperäistä painiketta, kuten:
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>
)
}
Se on todella mukavaa, koska se mahdollistaa useampien ohimenevien painikekomponenttien laajentamisen perustyypistämme. Kaikki kääntyy ja toimii odotetusti, paitsi Storybook...
Ongelma
En näytä löytävän mitään kysymyksiä/ongelmia nykyaikaisesta tarinakertojakomponentista, joka sallii geneeriset propsit.
ExtendedButtonProps tarina:
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',
}
Tässä on tsc-kääntäjän virhe, joka ilmenee ButtonExtendedProps-kohdassa yllä olevassa koodissa:
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)
Voiko joku huomata, mitä olen tässä ohittanut? Onko tarinakirjan dokumentaatiossa sivua, joka tarjoaa esimerkkejä tästä? Katselin ympäriinsä melko paljon tänään, mutta en ole varma, mitä avainsanoja pitäisi etsiä. Kaikki vinkit ovat erittäin tervetulleita. Kiitos.
Vastaus #1
Kuten käy ilmi, ComponentStory<typeof Button> === Story<ButtonProps>
Joten lopullinen tarinan allekirjoitus näytti tältä:
export const ButtonExtendedProps: Story<ButtonProps<ExtendedProps>> = ({
altIconType,
altClassName,
altAriaLabel,
children,
clean,
...props
}: ButtonProps<ExtendedProps>) => {
