Repository navigation
Angular: Keep the function control on constructor and generic signatures - #35921
Merged
valentinpalkovic merged 1 commit intoAug 17, 2026
Conversation
TypeIndex.render leads a constructor type with `new ` and a generic signature with its type parameters, but isFunctionTypeString only accepted a leading `(`. Both shapes therefore got a correct table.type.summary and lost the function control to the other/empty-enum catch-all. The generic case regressed in 3ab7fec, which added type-parameter rendering to fix invalid type text and paid for it with the control. The constructor case never had one. The new angular-cm tests go through the real analyzer rather than hand-written type strings, because the defect was a drift between what the renderer emits and what the predicate accepts; strings chosen by a test author would not have caught it.
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
Included review availability: 1 review is currently available. Based on recent review activity, included reviews refill at 3 per hour. WalkthroughChangesAngular function type detection
Merge Risk: ⚪ Minimal · up to This restores usable function controls for Angular constructor and generic function inputs without changing their displayed signatures; no actionable merge-blocking risk remains beyond normal checks and review. ✨ Finishing Touches📝 Generate docstrings
Comment |
huang-julien
approved these changes
Aug 17, 2026
valentinpalkovic
deleted the
valentin/sb-1809-bug-angular-constructor-and-generic-function-inputs-lose-the
branch
August 17, 2026 19:47
3 tasks done
huang-julien
added a commit
to storybookjs/sandboxes
that referenced
this pull request
Aug 18, 2026
Check the diff here: storybookjs/storybook@f96ed20...add38a0 List of included PRs since previous version: - storybookjs/storybook#35922 (valentin/sb-1766-angular-docgen-documentation-pass) - storybookjs/storybook#35844 (s-robertson/u/srobertson/fix-react-component-meta-union-props) - storybookjs/storybook#35931 (valentin/sb-1847-componentid-collision-warning) - storybookjs/storybook#35923 (valentin/sb-1789-server-side-code-snippets-resolve-spreads-and-identifier) - storybookjs/storybook#35940 (valentin/sb-1789-review-fixes) - storybookjs/storybook#35900 (julien/vue-api-description) - storybookjs/storybook#35938 (fix-publish-ansi-parsing) - storybookjs/storybook#35929 (valentin/sb-1821-pin-oxc-resolver) - storybookjs/storybook#35936 (chore/changelog-v10.5.9) - storybookjs/storybook#35930 (valentin/sb-1789-review-fixes) - storybookjs/storybook#35921 (valentin/sb-1809-bug-angular-constructor-and-generic-function-inputs-lose-the) - storybookjs/storybook#35917 (norbert/fix-publish-staged-retries) - storybookjs/storybook#35896 (valentin/sb-1776-angular-docs-end-to-end) - storybookjs/storybook#35920 (julien/vue_server_docgen_options) - storybookjs/storybook#35907 (valentin/docgen-server-arg-types) - storybookjs/storybook#35886 (valentin/sb-1799-default-docgen-server-angular-vite) - storybookjs/storybook#35902 (fix/vue-snippet-runtimeoverride) - storybookjs/storybook#35825 (norbert/module-graph-skip-noop-mirror) - storybookjs/storybook#35629 (reuben/fix-pseudo-states-cssom-rewrites) - storybookjs/storybook#35915 (next-merge-prerelease) - storybookjs/storybook#35906 (valentin/angular-docs-decorator-gate) - storybookjs/storybook#35830 (version-non-patch-from-10.6.0-alpha.5) - storybookjs/storybook#35899 (valentin/angular-required-input-with-default) - storybookjs/storybook#35831 (norbert/spike-module-graph-hot-cold-split)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I did
A function-typed Angular input shows its real signature in the props table since we started rendering signatures instead of a bare
function. Two shapes never got the second half of that deal, though: a constructor type (new (...) => T) and a generic signature (<T>(...) => T) both keep a correct summary but lose the function control and fall back to theother/empty-enumcatch-all, which the user sees as an unusable object control.The summary and the control are independent fields. Hence, there is no reason for getting one right to cost the other.
The cause is a drift between two places that have to agree.
TypeIndex.renderlearned to lead a constructor type withnewand a generic one with its type parameters, while the sbType predicate still only accepted a leading(:The generic half is a regression from
3ab7feccdc6, which added type-parameter rendering to fix invalid type text in generated metadata and quietly paid for it with the control. The constructor half never had a control to begin with.Solution
Teach the predicate the two prefixes the renderer actually emits:
The summary text is untouched - it was already right in both cases. The same predicate is duplicated verbatim in
@storybook/angular-compodoc(behind themodernflag), so it is fixed in both packages to stop the two paths drifting apart again.What changes, per declared input type:
table.type.summary(value: number) => string(value: number) => stringfunctionfunction(a?: string, ...rest: number[]) => void(a?: string, ...rest: number[]) => voidfunctionfunction<T>(value: T) => T<T>(value: T) => Tempty-enumfunctionnew (value: number) => Thingnew (value: number) => Thingempty-enumfunctionnew <T>(value: T) => Thingnew <T>(value: T) => Thingempty-enumfunctionOnly the control column moves.
Array<(value: number) => string>still does not read as a function, which is pinned by a negative test in both packages.This is what a bad run looks like, from the tests before the one-line fix:
Worth noting for reviewers: the new
angular-cmtests drive the real analyzer throughcomponentInrather than feeding the predicate hand-written type strings. That is deliberate. The defect is precisely a mismatch between what the renderer emits and what the predicate accepts, so strings picked by a test author would have sailed straight through the whole regression.No recorded baseline moved, since no fixture contained either shape.
One deviation worth flagging
The issue asked for the two shapes to be added to the
docgen-harnessfixture corpus as well. I skipped that on purpose.compodoc-input.jsonis a committed Compodoc 2.0.0 recording with no record script, Compodoc 2.0.0 crashes under TypeScript 7 in this repo, and that corpus exists to gate ACM against Compodoc - which collapses every function type tofunctionand therefore exercises none of this. I would argue it buys churn and a fragile regeneration step for zero signal, and that the package-level tests cover both shapes better. Happy to add it anyway if someone disagrees.Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
yarn task sandbox --template angular-vite/docgen-server-ts --start-from autocode/frameworks/angular-vite/template/stories/argTypes/doc-button/doc-button.component.tsin the sandbox and add two inputs to the component class:argTypes/doc-buttonstoryfactoryandmapperrowsExpected: the Type column shows the full signature (
new (value: number) => Dateand<T>(value: T) => T), and the Control column shows the function control placeholder. Before this PR both rows fell back to a raw JSON/object editor instead.Documentation
MIGRATION.MD
No documentation change needed - this restores intended behaviour on an existing field and adds no new API.
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsDeclare whether manual QA will be needed for this PR during the next release, through
qa:neededorqa:skipMake 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/coreteam 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>