Skip to content

Commit

Permalink
Added VarianceAwareType
Browse files Browse the repository at this point in the history
  • Loading branch information
vudaltsov committed Feb 22, 2024
1 parent 54f2b76 commit 806a27f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/TypeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ public function visitUnion(UnionType $type): mixed;
/** @return TReturn */
public function visitValueOf(ValueOfType $type): mixed;

/** @return TReturn */
public function visitVarianceAware(VarianceAwareType $type): mixed;

/** @return TReturn */
public function visitVoid(VoidType $type): mixed;
}
17 changes: 17 additions & 0 deletions src/Variance.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Typhoon\Type;

/**
* @api
* @psalm-immutable
*/
enum Variance
{
case INVARIANT;
case COVARIANT;
case CONTRAVARIANT;
case BIVARIANT;
}
38 changes: 38 additions & 0 deletions src/VarianceAwareType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Typhoon\Type;

/**
* @api
* @template-covariant TType
* @implements Type<TType>
*/
final class VarianceAwareType implements Type
{
/**
* @var Type<TType>
*/
public readonly Type $type;

public readonly Variance $variance;

/**
* @internal
* @psalm-internal Typhoon\Type
* @param Type<TType> $type
*/
public function __construct(
Type $type,
Variance $variance,
) {
$this->type = $type;
$this->variance = $variance;
}

public function accept(TypeVisitor $visitor): mixed
{
return $visitor->visitVarianceAware($this);
}
}
10 changes: 10 additions & 0 deletions src/types.php
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,16 @@ public static function valueOf(Type $type): ValueOfType
{
return new ValueOfType($type);
}

/**
* @template TType
* @param Type<TType> $type
* @return VarianceAwareType<TType>
*/
public static function varianceAware(Type $type, Variance $variance): VarianceAwareType
{
return new VarianceAwareType($type, $variance);
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions tests/PsalmTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public static function extractType(Type $_type): mixed
#[TestWith([__DIR__ . '/psalm/types.phpt'])]
#[TestWith([__DIR__ . '/psalm/UnionType.phpt'])]
#[TestWith([__DIR__ . '/psalm/ValueOfType.phpt'])]
#[TestWith([__DIR__ . '/psalm/VarianceAwareType.phpt'])]
#[TestWith([__DIR__ . '/psalm/VoidType.phpt'])]
public function testPhptFiles(string $phptFile): void
{
Expand Down
9 changes: 9 additions & 0 deletions tests/psalm/VarianceAwareType.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
--FILE--
<?php

namespace Typhoon\Type;

$_type = PsalmTest::extractType(new VarianceAwareType(StringType::type, Variance::INVARIANT));
/** @psalm-check-type-exact $_type = string */

--EXPECT--

0 comments on commit 806a27f

Please sign in to comment.