A key named first-name looks harmless in JSON. In the JSON converter, Laravel quotes it and the array syntax stays valid. TypeScript and the PHP DTO do not rename it. They copy the hyphen into the field. Conversion stays in the browser.

{"first-name":"Ada","role":"engineer"} 
[ 'first-name' => 'Ada', 'role' => 'engineer', ] 
export interface Root { first-name: string; role: string; } 
public string $first-name; 

The constructor uses that same name: $this->first-name = $data['first-name'] ?? null. The class around it is still DataTransferObject. Nothing in the draft renames the key or the class.

A list key loses one s

When a key holds an array of objects, the converter drops a single trailing s, then Pascal-cases what remains. items becomes Item. status becomes Statu.

export interface Root { status: Statu[]; } export interface Statu { code: string; } 

That came from {"status":[{"code":"ok"}]}. The PHP DTO does not emit Statu. The property is public array $status. Nested objects on the DTO are array, not child classes.

Before you ship the draft

Rename DataTransferObject. Replace a hyphen key with a name the language accepts. Do not trust Statu as a finished interface name. The converter drafts text from the first object when the root is an array. Later rows still appear in Laravel and in the CSV header.

A trailing comma clears the output. {"a":1,} produces Expected double-quoted property name in JSON at position 7 (line 1 column 8). Repair it in the JSON formatter, then convert again.

Guide: https://kepttools.com/guides/json-to-typescript-php-dto-laravel