smpita/typeas is a Laravel package for guaranteed type control for php.
It currently has 2 GitHub stars and 57.517 downloads on Packagist (latest version v4.2.0).
Install it with composer require smpita/typeas.
Discover more Laravel packages by smpita
or browse all Laravel packages to compare alternatives.
Last updated
Install the package via composer:
composer require smpita/typeas
See SIGNATURES for the full list of methods and signatures.
Pass a mixed variable to get a typed variable.
use Smpita\TypeAs\TypeAs;
// Throws \Smpita\TypeAs\TypeAsResolutionException if $mixed can't resolve to the type.
$array = TypeAs::array($mixed);
$bool = TypeAs::bool($mixed);
$class = TypeAs::class(Expected::class, $mixed);
$float = TypeAs::float($mixed);
$int = TypeAs::int($mixed);
$string = TypeAs::string($mixed);
// Returns null if $mixed can't resolve to the type.
$nullableArray = TypeAs::nullableArray($mixed);
$nullableBool = TypeAs::nullableBool($mixed);
$nullableClass = TypeAs::nullableClass(Expected::class, $mixed);
$nullableFloat = TypeAs::nullableFloat($mixed);
$nullableInt = TypeAs::nullableInt($mixed);
$nullableString = TypeAs::nullableString($mixed);
To suppress throwing exceptions, provide a default.
use Smpita\TypeAs\TypeAs;
// Returns the default if passed null, or if $mixed can't resolve to the type.
$array = TypeAs::array($mixed, []);
$bool = TypeAs::bool($mixed, false);
$class = TypeAs::class(Expected::class, $mixed, new StdClass());
$float = TypeAs::float($mixed, 0.0);
$int = TypeAs::int($mixed, 0);
$string = TypeAs::string($mixed, '');
// Nullable types can specify defaults.
$nullableArray = TypeAs::nullableArray($mixed, []);
$nullableBool = TypeAs::nullableBool($mixed, false);
$nullableClass = TypeAs::nullableClass(Expected::class, $mixed, new StdClass());
$nullableFloat = TypeAs::nullableFloat($mixed, 0.0);
$nullableInt = TypeAs::nullableInt($mixed, 0);
$nullableString = TypeAs::nullableString($mixed, '');
// As a named parameter
$array = TypeAs::array(value: $mixed, default: []);
By default, array() will wrap non-iterables similar to (array) $mixed instead of throwing exceptions.
use Smpita\TypeAs\TypeAs;
TypeAs::array('example'); // returns ['example']
TypeAs::array(['example']); // returns ['example']
/**
* Disable array wrapping to get exceptions.
* These throw \Smpita\TypeAs\TypeAsResolutionException
*/
TypeAs::array('example', wrap: false);
TypeAs::array('example', null, null, false);
As a convenience, TypeAs supports fluent syntax.
The NonNullable and Nullable fluent classes wrap the base TypeAs methods.
In performance critical environments, the standard methods are recommended.
use Smpita\TypeAs\TypeAs;
$array = TypeAs::type($mixed)->asArray();
$bool = TypeAs::type($mixed)->asBool();
$filterBool = TypeAs::type($mixed)->asFilterBool();
$class = TypeAs::type($mixed)->asClass(Expected::class);
$float = TypeAs::type($mixed)->asFloat();
$int = TypeAs::type($mixed)->asInt();
$string = TypeAs::type($mixed)->asString();
Chain nullable() for nullable returns.
Note: Moving between NonNullable and Nullable returns a new instance of the associated class.
use Smpita\TypeAs\TypeAs;
$nullableArray = TypeAs::type($mixed)
->nullable()
->asArray();
use Smpita\TypeAs\TypeAs;
$array = $typeAsNullableInstance
->nonNullable()
->asArray();
Chain using() to resolve using a Custom Resolver.
use Smpita\TypeAs\TypeAs;
$array = TypeAs::type($mixed)
->using(new CustomArrayResolver())
->asArray();
Chain default() to specify a default.
use Smpita\TypeAs\TypeAs;
$array = TypeAs::type($mixed)
->default([])
->asArray();
TypeAs::type('')->noWrap()->asArray();
TypeAs::type('')->wrap(false)->asArray();
use Smpita\TypeAs\TypeAs;
$instance = TypeAs::type($mixed);
$assignment = $instance; // $assignment mutates when $instance changes.
$copy = $instance->copy(); // $copy is unaffected by changes to $instance.
$clone = clone $instance; // $clone is unaffected by changes to $instance.
use Smpita\TypeAs\Fluent\Nullable;
use Smpita\TypeAs\Fluent\NonNullable;
// Returns \Smpita\TypeAs\Fluent\TypeConfig
$config = NonNullable::make()->config();
$config = Nullable::make()->config();
use Smpita\TypeAs\Fluent\Nullable;
use Smpita\TypeAs\Fluent\NonNullable;
use Smpita\TypeAs\Fluent\TypeConfig;
$config = new TypeConfig(
fromValue: $mixed,
defaultTo: $default,
resolveUsing: $resolver,
arrayWrap: null,
);
$nonNullable = NonNullable::make($config);
$nonNullable = (new NonNullable())->import($config);
$nullable = Nullable::make($config);
$nullable = (new Nullable())->import($config);
Use onError() to customize the throw message or exception.
Smpita\TypeAs\Exceptions\TypeAsResolutionExceptionuse Smpita\TypeAs\TypeAs;
// Static API
TypeAs::onError('Expected iterable, received %s', CustomResolutionException::class)
->array($mixed);
// Fluent API
TypeAs::type($mixed)
->onError('Expected iterable, received %s', CustomResolutionException::class)
->asArray();
Both arguments are optional.
// Custom message only
onError('Expected iterable, received %s')
// Custom Exception only
onError(exception: CustomResolutionException::class)
onError(null, CustomResolutionException::class)
Extensions are created by passing a custom resolver to a function.
/**
* @see \Smpita\TypeAs\Resolvers\Extensions\AsNullableFilterBool
*
* Uses FILTER_VALIDATE_BOOL
* https://www.php.net/manual/en/filter.constants.php#constant.filter-validate-bool
*
* Returns true on 1 1.0 "1" "true" "yes" "on"
* Returns false on 0 0.0 "0" "false" "no" "off" ""
*/
$filterBool = TypeAs::filterBool($mixed, $default);
$nullableFilterBool = TypeAs::nullableFilterBool($mixed, $default);
SIGNATURES#resolver-registration
Each base type has an associated interface located in Smpita\TypeAs\Contracts which you can implement to make your own resolvers.
Simply implement the interface, then either register the resolver or use it in the resolver method.
All resolvers extend the same interfaces. Non-nullable methods throw when null is returned by a resolver.
Smpita\TypeAs\Contracts\ArrayResolverSmpita\TypeAs\Contracts\BoolResolverSmpita\TypeAs\Contracts\ClassResolverSmpita\TypeAs\Contracts\FloatResolverSmpita\TypeAs\Contracts\IntResolverSmpita\TypeAs\Contracts\StringResolveruse Smpita\TypeAs\Contracts\StringResolver;
class CustomStringResolver implements StringResolver
{
/**
* Return null when unresolvable for default error handling.
*/
public function resolve(mixed $value, string $default = null): ?string
{
/**
* Your logic here
*
* Note:
* The resolver is responsible for returning $default when appropriate.
* See \Smpita\TypeAs\Resolvers for examples.
*/
}
}
To globally register a resolver, use the associated setter method. In Laravel, it's recommended to do this in the boot method of a ServiceProvider.
use Smpita\TypeAs\TypeAs;
TypeAs::setArrayResolver(new CustomArrayResolver());
TypeAs::setBoolResolver(new CustomBoolResolver());
TypeAs::setClassResolver(new CustomClassResolver());
TypeAs::setFloatResolver(new CustomFloatResolver());
TypeAs::setIntResolver(new CustomIntResolver());
TypeAs::setStringResolver(new CustomStringResolver());
To return to default, set the resolver to null.
use Smpita\TypeAs\TypeAs;
TypeAs::setArrayResolver(null);
TypeAs::setBoolResolver(null);
TypeAs::setClassResolver(null);
TypeAs::setFloatResolver(null);
TypeAs::setIntResolver(null);
TypeAs::setStringResolver(null);
// Return all resolvers to default
TypeAs::useDefaultResolvers();
Inject a resolver to use it on a per call basis.
use Smpita\TypeAs\TypeAs;
// Non-nullable methods
$array = TypeAs::array($mixed, resolver: new CustomArrayResolver());
$bool = TypeAs::bool($mixed, resolver: new CustomBoolResolver());
$class = TypeAs::class(Expected::class, $mixed, resolver: new CustomClassResolver());
$float = TypeAs::float($mixed, resolver: new CustomFloatResolver());
$int = TypeAs::int($mixed, resolver: new CustomIntResolver());
$string = TypeAs::string($mixed, resolver: new CustomStringResolver());
// Nullable methods use same resolver interface
$nullableArray = TypeAs::nullableArray($mixed, resolver: new CustomArrayResolver());
$nullableBool = TypeAs::nullableBool($mixed, resolver: new CustomBoolResolver());
$nullableClass = TypeAs::nullableClass(Expected::class, $mixed, resolver: new CustomClassResolver());
$nullableFloat = TypeAs::nullableFloat($mixed, resolver: new CustomFloatResolver());
$nullableInt = TypeAs::nullableInt($mixed, resolver: new CustomIntResolver());
$nullableString = TypeAs::nullableString($mixed, resolver: new CustomStringResolver());
// Or with positional params
$array = TypeAs::array($mixed, null, new CustomArrayResolver());
$string = TypeAs::string($mixed, null, new CustomStringResolver());
$nullableArray = TypeAs::nullableArray($mixed, null, new CustomArrayResolver());
$nullableString = TypeAs::nullableString($mixed, null, new CustomStringResolver());
If you registered a custom resolver then want to use a default resolver on a per call basis, pass the default resolver class.
use Smpita\TypeAs\TypeAs;
$array = TypeAs::array($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsArray());
$bool = TypeAs::bool($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsBool());
$class = TypeAs::class(Expected::class, $mixed, resolver: \Smpita\TypeAs\Resolvers\AsClass());
$float = TypeAs::float($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsFloat());
$int = TypeAs::int($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsInt());
$string = TypeAs::string($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsString());
// Nullable methods use same resolver classes
$nullableArray = TypeAs::nullableArray($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsArray());
$nullableBool = TypeAs::nullableBool($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsBool());
$nullableClass = TypeAs::nullableClass(Expected::class, $mixed, resolver: new \Smpita\TypeAs\Resolvers\AsClass());
$nullableFloat = TypeAs::nullableFloat($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsFloat());
$nullableInt = TypeAs::nullableInt($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsInt());
$nullableString = TypeAs::nullableString($mixed, resolver: new \Smpita\TypeAs\Resolvers\AsString());
Helpers follow standard signature patterns.
asClass(class: $expected, value: $mixed, default: $default, resolver: $resolver);
type($mixed)->default($default)->asClass($expected);
// Standard Helpers
$array = asArray($mixed);
$bool = asBool($mixed);
$filterBool = asFilterBool($mixed);
$class = asClass(Expected::class, $mixed);
$float = asFloat($mixed);
$int = asInt($mixed);
$string = asString($mixed);
$nullableArray = asNullableArray($mixed);
$nullableBool = asNullableBool($mixed);
$nullableFilterBool = asNullableFilterBool($mixed);
$nullableClass = asNullableClass(Expected::class, $mixed);
$nullableFloat = asNullableFloat($mixed);
$nullableInt = asNullableInt($mixed);
$nullableString = asNullableString($mixed);
// Fluent Helpers
$typed = type($mixed);
Each global helper has a local counterpart you can import if the global helper collides with another global method.
use function Smpita\TypeAs\asArray as TypeAsArray;
use function Smpita\TypeAs\asBool as TypeAsBool;
use function Smpita\TypeAs\asFilterBool as TypeAsFilterBool;
use function Smpita\TypeAs\asClass as TypeAsClass;
use function Smpita\TypeAs\asFloat as TypeAsFloat;
use function Smpita\TypeAs\asInt as TypeAsInt;
use function Smpita\TypeAs\asString as TypeAsString;
use function Smpita\TypeAs\asNullableArray as TypeAsNullableArray;
use function Smpita\TypeAs\asNullableBool as TypeAsNullableBool;
use function Smpita\TypeAs\asNullableFilterBool as TypeAsNullableFilterBool;
use function Smpita\TypeAs\asNullableClass as TypeAsNullableClass;
use function Smpita\TypeAs\asNullableFloat as TypeAsNullableFloat;
use function Smpita\TypeAs\asNullableInt as TypeAsNullableInt;
use function Smpita\TypeAs\asNullableString as TypeAsNullableString;
use function Smpita\TypeAs\type as TypeAsType;
Please see the Upgrade Guide and SIGNATURES#deprecations if you encounter a breaking change.
composer test
Please see RELEASES for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.