-
Notifications
You must be signed in to change notification settings - Fork 302
Typed properties #1168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Typed properties #1168
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1168 +/- ##
=======================================
Coverage 98.16% 98.17%
=======================================
Files 404 404
Lines 10632 10633 +1
=======================================
+ Hits 10437 10439 +2
+ Misses 195 194 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@thomascorthals I agree, we should do that for 7.0.0. |
93d0f39 to
7179cec
Compare
7179cec to
b9a37db
Compare
Hadn't really thought about that. Would add additional work on our side to keep them in sync. I was actually looking into getting the codebase to PHPStan level 2 and a lot of the errors seem to be caused by type hinting with interfaces that don't define all methods that are present in the implementing class. Here's an example, there are currently dozens like this. |
|
OK, then fix the existing interfaces and avoid further interfaces until required? |
|
I don't think we can "fix" the existing interfaces. I've done the PHPStan level 2 fixes in the code in my own branch because it's easier to just show what it takes: thomascorthals@a4c09bc. What can't be fixed with type declarations is usually fixable by type hinting. But that doesn't "fix" the interface. Take the public function build(QueryInterface $query): RequestIt can't be more specific than that because every class inheriting from it has a different public function build(QueryInterface|SelectQuery $query): RequestBecause of contravariance, we can make the accepted parameters wider. That's what the union type does. However, static analysis doesn't "know" that we're only ever passing There is a workaround for static analysis if you use intersection types. Because that means narrowing the accepted type for the method, it's not possible to do so in a type declaration. But PHPStan prioritises PHPDoc type hints over the actual type declaration. /**
* Build request for a select query.
*
* @param QueryInterface&SelectQuery $query
*
* @return Request
*/
public function build(QueryInterface|SelectQuery $query): RequestThis is the best solution I could come up with for the current structure of our codebase. It doesn't break backward compatibility, PHPStan knows what to do, IDEs know what to do, humans get the intent. |
A new major version is the perfect opportunity to do some overhaul on the codebase. I've replaced the type hints with actual type declarations on class properties (introduced in PHP 7.4). And I've added union type declarations to method signatures (introduced in PHP 8.0) where this was previously also only done in type hints.
This is a breaking change for anyone extending our codebase, which I've added to the pitfalls. But it shouldn't break much for regular use of the library since I didn't have to change anything in the integration tests and they still pass.