TypeScript
This package can convert Bag Value Objects to TypeScript types using the spatie/typescript-transformer package.
Bag will automatically convert Optional
properties to TypeScript property?: otherTypes
properties, and will apply output name mapping to the property names to match JSON output.
Configuration
To configure the spatie/typescript-transformer
package to transform Bags correctly.
Laravel
If you are using Bag with Laravel and the spatie/laravel-typescript-transformer
package, you must replace the Spatie\TypeScriptTransformer\Transformers\DtoTransformer
with the \Bag\TypeScript\BagTransformer
in the transformers
array of the config/typescript-transformer.php
configuration file:
'transformers' => [
Spatie\LaravelTypeScriptTransformer\Transformers\SpatieStateTransformer::class,
Spatie\TypeScriptTransformer\Transformers\SpatieEnumTransformer::class,
-- Spatie\TypeScriptTransformer\Transformers\DtoTransformer::class,
++ Bag\TypeScript\BagTransformer::class,
],
Framework Agnostic
If you are not using Laravel, you can follow the instruction here, and just be sure to add the \Bag\TypeScript\BagTransformer
to the transformers()
method call.
Usage
Once the package has been configured, you can use the spatie/typescript-transformer
package as normal, and Bags will be transformed as expected.
For example, running the transformer with the following Bag:
namespace App\Values;
use Bag\Attributes\MapOutputName;
use Bag\Bag;
use Bag\Mappers\SnakeCase;
use Bag\Values\Optional;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
#[TypeScript]
#[MapOutputName(SnakeCase::class)]
class MyValue extends Bag
{
public function __construct(
public string $name,
public Optional|int $age,
public Optional|string|null $emailAddress = null,
) {}
}
will result in output something like:
declare namespace App.Values {
export type MyValue = {
name: string;
age?: number;
email_address?: string | null;
};
}
WARNING
If you do not make the necessary configuration changes, Bags will not be transformed correctly, resulting instead in property: any | otherTypes
.
Collections
If you want to output Bag Collections as types, in addition to the #[TypeScript]
annotation, you can also add a #[LiteralTypeScriptType]
annotation to map it to a typed array of the Value object type:
namespace App\Values\Collections;
use Bag\Collection;
use Spatie\TypeScriptTransformer\Attributes\LiteralTypeScriptType;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
#[TypeScript];
#[LiteralTypeScriptType('App.Values.MyValue[]')]
class MyValueCollection extends Collection
{
}
Which will result in TypeScript output similar to:
declare namespace App.Values.Collections {
export type MyValueCollection = App.Values.MyValue[];
}