Prevent TooManyTemplateParams on Factory subclasses without own template params#682
Prevent TooManyTemplateParams on Factory subclasses without own template params#682
TooManyTemplateParams on Factory subclasses without own template params#682Conversation
…template params When a user-space base factory overrides new() with `@return static<TModel>`, Psalm resolves the return to e.g. `UserFactory<User>`. But UserFactory has 0 own template params (it binds TModel via @extends), triggering TooManyTemplateParams. Add AfterMethodCallAnalysis handler that strips excess template args by replacing TGenericObject with TNamedObject for Factory subclasses with no own template params. Closes #677
There was a problem hiding this comment.
Pull request overview
Adds a Psalm hook to prevent TooManyTemplateParams errors when Factory::new() return types get resolved into ChildFactory<Model> even though the child factory declares no template params of its own (binding via @extends).
Changes:
- Register a new
AfterMethodCallAnalysishook to strip excess template args fromFactorysubclass return types when the subclass declares zero own templates. - Add a new handler (
FactoryReturnTypeProvider) implementing the template-guard logic. - Add a type test covering both an intermediate base-factory pattern and the direct-subclass pattern.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
tests/Type/tests/FactoryTooManyTemplateParamsTest.phpt |
Adds a regression test ensuring factory subclasses without own template params don’t end up as ChildFactory<Model> in inferred types. |
src/Plugin.php |
Registers the new factory return-type guard hook. |
src/Handlers/Eloquent/FactoryReturnTypeProvider.php |
Implements the AfterMethodCallAnalysis handler that replaces invalid TGenericObject factory subclasses with TNamedObject. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Issue to Solve
When a user-space base factory overrides
new()with@return static<TModel>, Psalm resolves the return to e.g.UserFactory<User>. ButUserFactoryhas 0 own template params (it bindsTModelvia@extends), so Psalm emitsTooManyTemplateParams.Related
Closes #677
Solution Description
Add an
AfterMethodCallAnalysishandler that strips excess template args from Factory subclass return types. For anyTGenericObjectin the return type that is a Factory subclass with no own template params, it replaces it with a plainTNamedObject.Includes a type test covering both the intermediate-factory pattern and the standard direct-subclass pattern.
Checklist
tests/Type/)