-
Notifications
You must be signed in to change notification settings - Fork 471
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Get closer to how type inference in TypeScript works
See https://javascript.xgqfrms.xyz/pdfs/TypeScript%20Language%20Specification.pdf - section 3.11.7 Type Inference about union types Otherwise, if T is a union or intersection type: * First, inferences are made from S to each constituent type in T that isn't simply one of the type parameters for which inferences are being made. * If the first step produced no inferences then if T is a union type and exactly one constituent type in T is simply a type parameter for which inferences are being made, inferences are made from S to that type parameter.
- Loading branch information
1 parent
c9b5c12
commit 3be90f0
Showing
4 changed files
with
103 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<?php | ||
|
||
namespace Bug4803; | ||
|
||
use function PHPStan\Analyser\assertType; | ||
|
||
/** | ||
* @template T of object | ||
*/ | ||
interface Proxy {} | ||
|
||
class Foo | ||
{ | ||
|
||
/** | ||
* @template T of object | ||
* @param Proxy<T>|T $proxyOrObject | ||
* @return T | ||
*/ | ||
public function doFoo($proxyOrObject) | ||
{ | ||
assertType('Bug4803\Proxy<T of object (method Bug4803\Foo::doFoo(), argument)>|T of object (method Bug4803\Foo::doFoo(), argument)', $proxyOrObject); | ||
} | ||
|
||
/** @param Proxy<\stdClass> $proxy */ | ||
public function doBar($proxy): void | ||
{ | ||
assertType('stdClass', $this->doFoo($proxy)); | ||
} | ||
|
||
/** @param \stdClass $std */ | ||
public function doBaz($std): void | ||
{ | ||
assertType('stdClass', $this->doFoo($std)); | ||
} | ||
|
||
/** @param Proxy<\stdClass>|\stdClass $proxyOrStd */ | ||
public function doLorem($proxyOrStd): void | ||
{ | ||
assertType('stdClass', $this->doFoo($proxyOrStd)); | ||
} | ||
|
||
} | ||
|
||
interface ProxyClassResolver | ||
{ | ||
/** | ||
* @template T of object | ||
* @param class-string<Proxy<T>>|class-string<T> $className | ||
* @return class-string<T> | ||
*/ | ||
public function resolveClassName(string $className): string; | ||
} | ||
|
||
final class Client | ||
{ | ||
private ProxyClassResolver $proxyClassResolver; | ||
|
||
public function __construct(ProxyClassResolver $proxyClassResolver) | ||
{ | ||
$this->proxyClassResolver = $proxyClassResolver; | ||
} | ||
|
||
/** | ||
* @template T of object | ||
* @param class-string<Proxy<T>>|class-string<T> $className | ||
* @return class-string<T> | ||
*/ | ||
public function getRealClass(string $className): string | ||
{ | ||
assertType('class-string<Bug4803\Proxy<T of object (method Bug4803\Client::getRealClass(), argument)>>|class-string<T of object (method Bug4803\Client::getRealClass(), argument)>', $className); | ||
|
||
$result = $this->proxyClassResolver->resolveClassName($className); | ||
assertType('class-string<T of object (method Bug4803\Client::getRealClass(), argument)>', $result); | ||
|
||
return $result; | ||
} | ||
} |
This file contains 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