Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ composer require typhoon/type
## Usage

```php
use Typhoon\types;
use Typhoon\Type\types;

/**
* array{
Expand All @@ -28,17 +28,17 @@ use Typhoon\types;
* ...
* }
*/
$type = types::unsealedShape([
$type = types::arrayShape([
types::nonEmptyString,
'a' => types::optional(types::union(types::int, types::float)),
'b' => types::object(Traversable::class, types::numericString, types::false),
'c' => types::callable(
parameters: [
types::classConstant(PDO::class, '*'),
types::defaultParam(types::classTemplate(Generator::class, 'TSend')),
types::variadicParam(types::scalar),
types::param(types::classTemplate(Generator::class, 'TSend'), hasDefault: true),
types::param(types::scalar, variadic: true),
],
returnType: types::void,
),
]);
], sealed: false);
```
2 changes: 1 addition & 1 deletion src/ShapeElement.php → src/ArrayElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @psalm-immutable
* @template-covariant TType
*/
final class ShapeElement
final class ArrayElement
{
/**
* @var Type<TType>
Expand Down
10 changes: 5 additions & 5 deletions src/ShapeType.php → src/ArrayShapeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
* @template-covariant TArray of array
* @implements Type<TArray>
*/
final class ShapeType implements Type
final class ArrayShapeType implements Type
{
/**
* @var array<ShapeElement>
* @var array<ArrayElement>
*/
public readonly array $elements;

Expand All @@ -22,18 +22,18 @@ final class ShapeType implements Type
/**
* @internal
* @psalm-internal Typhoon\Type
* @param array<ShapeElement> $elements
* @param array<ArrayElement> $elements
*/
public function __construct(
array $elements = [],
bool $sealed = true,
) {
$this->sealed = $sealed;
$this->elements = $elements;
$this->sealed = $sealed;
}

public function accept(TypeVisitor $visitor): mixed
{
return $visitor->visitShape($this);
return $visitor->visitArrayShape($this);
}
}
2 changes: 1 addition & 1 deletion src/TypeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function visitNonEmptyList(NonEmptyListType $type): mixed;
public function visitList(ListType $type): mixed;

/** @return TReturn */
public function visitShape(ShapeType $type): mixed;
public function visitArrayShape(ArrayShapeType $type): mixed;

/** @return TReturn */
public function visitNonEmptyArray(NonEmptyArrayType $type): mixed;
Expand Down
58 changes: 8 additions & 50 deletions src/types.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,50 +211,30 @@ public static function list(Type $valueType = self::mixed): ListType

/**
* @psalm-pure
* @param array<Type|ShapeElement> $elements
* @param array<Type|ArrayElement> $elements
*/
public static function shape(array $elements = [], bool $sealed = true): ShapeType
public static function arrayShape(array $elements = [], bool $sealed = true): ArrayShapeType
{
return new ShapeType(
return new ArrayShapeType(
array_map(
static fn (Type|ShapeElement $element): ShapeElement => $element instanceof Type
? new ShapeElement($element)
static fn (Type|ArrayElement $element): ArrayElement => $element instanceof Type
? new ArrayElement($element)
: $element,
$elements,
),
$sealed,
);
}

/**
* @psalm-pure
* @param array<Type|ShapeElement> $elements
*/
public static function unsealedShape(array $elements = []): ShapeType
{
return self::shape($elements, false);
}

/**
* @psalm-pure
* @template TType
* @param Type<TType> $type
* @return ShapeElement<TType>
*/
public static function element(Type $type, bool $optional): ShapeElement
{
return new ShapeElement($type, $optional);
}

/**
* @psalm-pure
* @template TType
* @param Type<TType> $type
* @return ShapeElement<TType>
* @return ArrayElement<TType>
*/
public static function optional(Type $type): ShapeElement
public static function arrayElement(Type $type, bool $optional = false): ArrayElement
{
return new ShapeElement($type, true);
return new ArrayElement($type, $optional);
}

/**
Expand Down Expand Up @@ -343,28 +323,6 @@ public static function param(Type $type = self::mixed, bool $hasDefault = false,
return new Parameter($type, $hasDefault, $variadic);
}

/**
* @psalm-pure
* @template TType
* @param Type<TType> $type
* @return Parameter<TType>
*/
public static function defaultParam(Type $type = self::mixed): Parameter
{
return new Parameter($type, true);
}

/**
* @psalm-pure
* @template TType
* @param Type<TType> $type
* @return Parameter<TType>
*/
public static function variadicParam(Type $type = self::mixed): Parameter
{
return new Parameter($type, variadic: true);
}

/**
* @psalm-pure
* @template TReturn
Expand Down
20 changes: 20 additions & 0 deletions tests/psalm/ArrayShapeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Typhoon\Type;

/** @psalm-check-type-exact $_emptyShape = array */
$_emptyShape = extractType(new ArrayShapeType());

/** @var ArrayShapeType<array{a?: string, 10: int}> */
$_shapeType = new ArrayShapeType([

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test really work?
This type cannot be inferred without a plugin.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't, that's why there is a @var forced type above :)

'a' => new ArrayElement(StringType::type, optional: true),
10 => new ArrayElement(IntType::type),
]);
/** @psalm-check-type-exact $_shape = array{a?: string, 10: int} */
$_shape = extractType($_shapeType);

function testShapeIsCovariant(ArrayShapeType $_type): void {}

testShapeIsCovariant($_shapeType);
20 changes: 0 additions & 20 deletions tests/psalm/ShapeTest.php

This file was deleted.