j0hnys/trident-typed 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

j0hnys/trident-typed

Composer 安装命令:

composer require j0hnys/trident-typed

包简介

Improvements to PHP's type system in userland: generics, typed lists, tuples and structs

README 文档

README

This package is a mere proof of concept about what's possible in PHP's userland to improve type checking. It adds support for type inference, generics, union types, typed lists, tuples and structs. Because all is done in userland, there are limitations on what syntax is possible.

Installation

You can install the package via composer:

composer require j0hnys/trident-typed

Usage

Type inference

Both collections, tuples and structs support inferred types. This means that all examples are also possible, without manually specifying types. For example:

// This collection will only allow objects of type `Post` in it.
$postCollection = new Collection([new Post()]);

// This tuple will keep its signature of (Point, Point).
$vector = new Tuple(new Point(30, 5), new Point(120, 0));

// This struct's fields are autmoatically type checked.
$struct = [
    'foo' => new Post(),
    'bar' => function () {
        // ...
    },
];

The following examples all show the manual type configuration. There are some cases where type inference falls short, and you have to fall back on manually defining them. You might also prefer the manual approach, for clarity's sake.

Note that type may be partially inferred. Some fields in tuples or structs may be type definitions, others may be real values. Uninitialised types will throw an error on read.

Typed lists and collections:

$list = new Collection(T::bool());

$list[] = new Post(); // TypeError

It's possible to directly initialise a collection with data after construction.

$list = (new Collection(T::string()))->set(['a', 'b', 'c']);

This package also provides some predefined lists, as shortcuts.

$list = new IntegerList([1, 4]);

$list[] = 'a'; // TypeError

Maps:

$map = new Map(T::string(),T::integer());

$map['name'] = 1;

$map[] = new Post(); // TypeError
$map[] = 1; // TypeError

It's possible to directly initialise a collection with data after construction.

$map = (new Map(T::string(),T::integer()))->set(['a'=>2]);

Generics:

Generic types wrap around classes, allowing you to not creating a custom type for every class.

$postList = new Collection(T::generic(Post::class));

$postList[] = 1; // TypeError

Tuples:

$point = new Tuple(T::float(), T::float());

$point[0] = 1.5;
$point[1] = 3;

$point[0] = 'a'; // TypeError
$point['a'] = 1; // TypeError
$point[10] = 1; // TypeError

Like lists, a tuple can also be given some data after construction with the set function.

$tuple = (new Tuple(T::string(), T::array()))->set('abc', []);

Structs:

$developer = new Struct([
    'name' => T::string(),
    'age' => T::int(),
    'second_name' => T::nullable(T::string()),
]);

$developer['name'] = 'Brent';
$developer['second_name'] = 'John';

$developer->set([
    'name' => 'BrenDt',
    'age' => 23,
    'second_name' => null,
]);

echo $developer->age;

$developer->name = 'Brent';

$developer->age = 'abc' // TypeError
$developer->somethingElse = 'abc' // TypeError

Nullable type

A nullable type can be defined in two, functionally identical, ways:

$list1 = new Collection(T::int()->nullable());

$list2 = new Collection(T::nullable(T::int()));

Union Type

A union type means a collection of multiple types.

$list = new Collection(T::union(T::int(), T::float()));

$list[] = 1;
$list[] = 1.1;

$list[] = 'abc'; // TypeError

Union types may also be nullable and contain generics.

What's not included:

  • Proper syntax.
  • IDE auto completion for generic types.
  • Prevention of type casting between scalar types.
  • Type hint generics in functions.

Creating your own types

The GenericType or T::generic() can be used to create structures of that type. It is, however, also possible to create your own types without generics. Let's take the example of Post. The generic approach works without adding custom types.

$postList = new Collection(T::generic(Post::class));

$postList[] = new Post();
$postList[] = 1; // TypeError 

The generic part can be skipped if you create your own type.

use J0hnys\Typed\Type;
use J0hnys\Typed\Types\Nullable;

class PostType implements Type
{
    use Nullable;
    
    public function validate($post): Post
    {
        return $post;
    }
}

Now you can use PostType directly:

$postList = new Collection(new PostType());

You're also free to extend the T helper.

class T extends J0hnys\Typed\T
{
    public static function post(): PostType
    {
        return new PostType();
    }
}

// ...

$postList = new Collection(T::post());

The Nullable trait adds the following simple snippet, so that the type can be made nullable when used.

public function nullable(): NullType
{
    return new NullType($this);
}

Note: It's recommended to also implement __toString in your own type classes.

Extending data structures

You're free to extend the existing data structures. For example, you could make shorthand tuples like so:

class Coordinates extends Tuple
{
    public function __construct(int $x, int $y)
    {
        parent::__construct(T::int(), T::int());

        $this[0] = $x;
        $this[1] = $y;
    }
}

j0hnys/trident-typed 适用场景与选型建议

j0hnys/trident-typed 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 146 次下载、GitHub Stars 达 0, 最近一次更新时间为 2019 年 08 月 09 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「typed」 「generics」 「tuple」 「structs」 「typed list」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 j0hnys/trident-typed 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 j0hnys/trident-typed 我们能提供哪些服务?
定制开发 / 二次开发

基于 j0hnys/trident-typed 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 146
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2019-08-09