From 904ac29481bcabff5f68dc546489d87c6d7c1532 Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Tue, 15 Nov 2022 09:59:00 +0100 Subject: [PATCH] Fix type inference bug with decorators --- .../renderers/react/src/public-types.test.tsx | 20 ++++++++++++++++--- code/renderers/react/src/public-types.ts | 13 +++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/code/renderers/react/src/public-types.test.tsx b/code/renderers/react/src/public-types.test.tsx index 204ea0df26ab..68b68fd23b28 100644 --- a/code/renderers/react/src/public-types.test.tsx +++ b/code/renderers/react/src/public-types.test.tsx @@ -1,7 +1,7 @@ import { describe, test } from '@jest/globals'; import { satisfies } from '@storybook/core-common'; -import type { StoryAnnotations } from '@storybook/types'; +import type { Args, StoryAnnotations, StrictArgs } from '@storybook/types'; import { expectTypeOf } from 'expect-type'; import type { KeyboardEventHandler, ReactNode } from 'react'; import React from 'react'; @@ -11,7 +11,7 @@ import type { SetOptional } from 'type-fest'; import type { Decorator, Meta, StoryObj } from './public-types'; import type { ReactRenderer } from './types'; -type ReactStory = StoryAnnotations; +type ReactStory = StoryAnnotations; type ButtonProps = { label: string; disabled: boolean }; const Button: (props: ButtonProps) => JSX.Element = () => <>; @@ -172,10 +172,24 @@ describe('Story args can be inferred', () => { ); + // decorator is not using args + const thirdDecorator: Decorator = (Story) => ( + <> + + + ); + + // decorator is not using args + const fourthDecorator: Decorator = (Story) => ( + <> + + + ); + const meta = satisfies>()({ component: Button, args: { disabled: false }, - decorators: [withDecorator, secondDecorator], + decorators: [withDecorator, secondDecorator, thirdDecorator, fourthDecorator], }); const Basic: StoryObj = { diff --git a/code/renderers/react/src/public-types.ts b/code/renderers/react/src/public-types.ts index 99212af7df4f..d488f686a5fa 100644 --- a/code/renderers/react/src/public-types.ts +++ b/code/renderers/react/src/public-types.ts @@ -54,15 +54,22 @@ export type StoryObj = TMetaOrCmpOrArgs extends { ? StoryAnnotations< ReactRenderer, TArgs, - SetOptional)>> + SetOptional)> > : never : TMetaOrCmpOrArgs extends ComponentType ? StoryAnnotations> : StoryAnnotations; -type ActionArgs = { - [P in keyof RArgs as ((...args: any[]) => void) extends RArgs[P] ? P : never]: RArgs[P]; +type ActionArgs = { + // This can be read as: filter TArgs on functions where we can assign a void function to that function. + // The docs addon argsEnhancers can only safely provide a default value for void functions. + // Other kind of required functions should be provided by the user. + [P in keyof TArgs as TArgs[P] extends (...args: any[]) => any + ? ((...args: any[]) => void) extends TArgs[P] + ? P + : never + : never]: TArgs[P]; }; /**