Skip to content

Preact: Support inferring props from component types#33828

Merged
kasperpeulen merged 4 commits intostorybookjs:nextfrom
JoviDeCroock:add-preact-inferred-types
Feb 13, 2026
Merged

Preact: Support inferring props from component types#33828
kasperpeulen merged 4 commits intostorybookjs:nextfrom
JoviDeCroock:add-preact-inferred-types

Conversation

@JoviDeCroock
Copy link
Copy Markdown
Contributor

@JoviDeCroock JoviDeCroock commented Feb 12, 2026

Relates to #33749

What I did

Meta<typeof Button> in @storybook/preact doesn't extract props correctly, forcing users to pass props types directly (Meta<ButtonProps>) as a workaround. The root cause: PreactRenderer.component was typed as AnyComponent<any, any> (discarding prop info), and Meta/StoryFn/StoryObj lacked the conditional ComponentProps extraction logic that the React renderer has.

Changes

  • types.tscomponent: AnyComponent<any, any>AnyComponent<this['T'], any> to bind props via the T slot.
  • public-types.tsMeta, StoryFn, and StoryObj now use conditional types to detect ComponentType and extract ComponentProps, with full ArgsFromMeta inference and SetOptional support for StoryObj<typeof meta> — mirroring the React renderer.
  • public-types.test.tsx (new) — Type-level test suite covering props extraction, partial/missing args errors, meta inference, interfaces, no-props components, render/decorator arg widening.

Result

// ✅ This now works — no workaround needed
const meta = { component: Button } satisfies Meta<typeof Button>;
type Story = StoryObj<typeof meta>; // correctly infers ButtonProps

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Testing should be surfaced by the types in the repository

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Improvements

    • Enhanced type inference for component props and story arguments.
    • Added StoryContext and Preview types for better TypeScript support.
    • Improved handling of mocked function properties in stories.
  • Tests

    • Added comprehensive type validation tests for component typing with Storybook integration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

Enhanced Preact renderer TypeScript types: Meta, StoryFn, and StoryObj now infer component props when given a ComponentType; AddMocks added to handle mocked function args; StoryContext and Preview exported; comprehensive type-only tests added; PreactRenderer.component typing tightened to depend on the renderer generic.

Changes

Cohort / File(s) Summary
Preact Public Type System
code/renderers/preact/src/public-types.ts
Reworked Meta, StoryFn, and StoryObj to conditionally derive args from a ComponentType (using ComponentProps), added AddMocks to preserve mocked function shapes from default args, applied SetOptional/Simplify for default-arg merging, and exported StoryContext and Preview.
Type Tests
code/renderers/preact/src/public-types.test.tsx
Added extensive type-only tests validating inference for component-based and direct-args metas, required vs optional args, decorators and render functions widening types, StoryObj generics and upcasts, and mock-function handling (using expect-type and @ts-expect-error).
Renderer Component Typing
code/renderers/preact/src/types.ts
Tightened PreactRenderer.component from AnyComponent<any, any> to AnyComponent<this['T'], any>, binding the component type parameter to the renderer generic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
code/renderers/preact/src/public-types.test.tsx (1)

191-191: Consider moving withDecorator inside the describe block.

withDecorator is defined between two it blocks at the describe level (Line 191), but it's only used inside the second it (Line 199). Moving it inside the describe block (e.g., before the it that uses it) or directly into the test would improve locality.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@code/renderers/preact/src/public-types.ts`:
- Around line 28-30: The StoryObj types lose Jest mock function types because
AddMocks is missing; add the AddMocks<TArgs, DefaultArgs> utility (using
Simplify and the conditional that keeps DefaultArgs[T] when it has a .mock)
before the Decorator export, then change the StoryObj return type to use
StoryAnnotations<PreactRenderer, AddMocks<TArgs, DefaultArgs>,
SetOptional<TArgs, keyof TArgs & keyof DefaultArgs>> instead of the current
plain TArgs usage so meta.args preserves Mock types; finally add a unit test in
public-types.test.tsx mirroring React's mock-function test to verify mock
methods remain typed.
🧹 Nitpick comments (1)
code/renderers/preact/src/public-types.test.tsx (1)

171-205: Consider adding type-level tests for StoryFn.

StoryFn was also updated with conditional ComponentType extraction in public-types.ts (lines 37–39), but this test file only exercises Meta and StoryObj. Adding a few StoryFn assertions (e.g., StoryFn<typeof Button> and StoryFn<ButtonProps>) would close that gap.

@JoviDeCroock JoviDeCroock force-pushed the add-preact-inferred-types branch from 75ca8c9 to 38aee8d Compare February 12, 2026 06:40
@bluetidepro
Copy link
Copy Markdown
Contributor

This will be extremely useful, thank you for fixing this!

@kasperpeulen kasperpeulen changed the title Support inferring props in preact Preact: Support inferring props from component types Feb 13, 2026
Copy link
Copy Markdown
Member

@kasperpeulen kasperpeulen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Clean 1:1 port of React's type inference to the Preact renderer.

@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot bot commented Feb 13, 2026

Package Benchmarks

Commit: 426ea04, ran on 13 February 2026 at 10:46:46 UTC

The following packages have significant changes to their size or dependencies:

@storybook/preact

Before After Difference
Dependency count 2 2 0
Self size 16 KB 23 KB 🚨 +7 KB 🚨
Dependency size 32 KB 32 KB 0 B
Bundle Size Analyzer Link Link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants