What happened?
While using spatie/laravel-typescript-transformer, I noticed that a property typed as /** @var string[]|Collection<int, string> */ can produce string[] | string[] in the generated TypeScript output (only when the fix in PR #136 is present, though).
This becomes apparent when two conditions are met:
- The
FixArrayLikeStructuresClassPropertyProcessor is configured to replace array-like classes (as laravel-typescript-transformer does by registering Collection::class and EloquentCollection::class)
- The docblock union contains both an explicit array type and an array-like class that resolves to the same array shape after transformation
While the issue manifests when using the Laravel package, the root cause is in the core typescript-transformer package's transformation pipeline, so it should probably be addressed here.
When a property has a PHPDoc union type that includes both an array-like class (e.g. Collection<int, string>) and its equivalent array type (e.g. string[]), the generated TypeScript output contains duplicate union members like string[] | string[].
TypeScriptUnion deduplicates its members in the constructor via the UniqueTypeScriptNodes trait. At construction time, the two members are different node types (TypeScriptGeneric for Collection and TypeScriptArray for string[]), so both are kept.
FixArrayLikeStructuresClassPropertyProcessor then runs and replaces the TypeScriptGeneric(Collection, ...) node with TypeScriptArray([string]) via a Visitor. Now both members are identical, but deduplication has already run and is not triggered again.
A possible fix could be to add a DeduplicateUnionTypesClassPropertyProcessor that runs as the last processor in the chain. It would walk the type tree and re-deduplicate any TypeScriptUnion members after all other processors have finished their transformations.
How to reproduce the bug
Given a class with a property typed as:
/** @var Collection<int, string>|string[] */
public array $items;
When FixArrayLikeStructuresClassPropertyProcessor is configured to replace Collection, the output is:
items: string[] | string[]
Instead of the expected:
Package Version
3.1.1
PHP Version
8.5.4
Which operating systems does with happen with?
macOS
Notes
No response
What happened?
While using
spatie/laravel-typescript-transformer, I noticed that a property typed as/** @var string[]|Collection<int, string> */can producestring[] | string[]in the generated TypeScript output (only when the fix in PR #136 is present, though).This becomes apparent when two conditions are met:
FixArrayLikeStructuresClassPropertyProcessoris configured to replace array-like classes (aslaravel-typescript-transformerdoes by registeringCollection::classandEloquentCollection::class)While the issue manifests when using the Laravel package, the root cause is in the core
typescript-transformerpackage's transformation pipeline, so it should probably be addressed here.When a property has a PHPDoc union type that includes both an array-like class (e.g.
Collection<int, string>) and its equivalent array type (e.g.string[]), the generated TypeScript output contains duplicate union members likestring[] | string[].TypeScriptUniondeduplicates its members in the constructor via theUniqueTypeScriptNodestrait. At construction time, the two members are different node types (TypeScriptGenericfor Collection andTypeScriptArrayforstring[]), so both are kept.FixArrayLikeStructuresClassPropertyProcessorthen runs and replaces theTypeScriptGeneric(Collection, ...)node withTypeScriptArray([string])via aVisitor. Now both members are identical, but deduplication has already run and is not triggered again.A possible fix could be to add a
DeduplicateUnionTypesClassPropertyProcessorthat runs as the last processor in the chain. It would walk the type tree and re-deduplicate anyTypeScriptUnionmembers after all other processors have finished their transformations.How to reproduce the bug
Given a class with a property typed as:
When
FixArrayLikeStructuresClassPropertyProcessoris configured to replaceCollection, the output is:Instead of the expected:
Package Version
3.1.1
PHP Version
8.5.4
Which operating systems does with happen with?
macOS
Notes
No response