A transformer is a class that implements the Transformer interface:
use Spatie\TypeScriptTransformer\Transformers\Transformer;
class EnumTransformer implements Transformer
{
public function transform(ReflectionClass $class, string $name): ?TransformedType
{
}
}
In the transform method, you should transform a PHP ReflectionClass into a TransformedType. This TransformedType will
include the TypeScript representation of the PHP class and some extra information.
When a transformer cannot transform the given ReflectionClass then the method should return null, indicating that the transformer is not suitable for the type.
##Creating transformed types
A TransformedType always has three properties: the ReflectionClass of the type you're transforming, the name of the
type and, of course, the transformed TypeScript code:
TransformedType::create(
ReflectionClass $class,
string $name,
string $transformed
);
For types that depend on other types a fourth argument can be passed to the create method:
TransformedType::create(
ReflectionClass $class,
string $name,
string $transformed,
MissingSymbolsCollection $missingSymbols
);
A MissingSymbolsCollection will contain references to other types. The package will replace these references with
correct TypeScript types.
Consider the following class as an example:
class User extends DataTransferObject
{
public string $name;
public RoleEnum $role;
}
As you can see, it has a RoleEnum as a property, which looks like this:
class RoleEnum extends Enum
{
const GUEST = 'guest';
const ADMIN = 'admin';
}
When transforming the User class we don't have any context or types for the RoleEnum. The transformer can register
this missing symbols for a property using the MissingSymbolsCollection as such:
$type = $missingSymbols->add(RoleEnum::class);
The add method will return a token that can be used in your transformed type. It's a link between the two types and
will later be replaced by the actual type implementation.
When no type was found (for example: because it wasn't converted to TypeScript), the type will default to
TypeScript's any type.
In the end, the package will produce the following output:
export type RoleEnum = 'guest' | 'admin';
export type User = {
name: string;
role: RoleEnum;
}
##Inline types
It is also possible to create an inline type. These types are replaced directly in other types. You can read more about
inline types here.
Inline types can be created like a regular TransformedType but they do not need a name:
TransformedType::createInline(
ReflectionClass $class,
string $transformed
);
When required you can also add a MissingSymbolsCollection:
TransformedType::createInline(
ReflectionClass $class,
string $transformed,
MissingSymbolsCollection $missingSymbols
);
When you create a new transformer, don't forget to add it to the list of transformers in your configuration!