DEV Community

Ameen Usman
Ameen Usman

Posted on Originally published at kepttools.com

What a JSON converter drafts from the first object

I had an API payload in one window and a blank TypeScript file in the other. The payload was a list of people. Each object carried an id, a name, a role, and a meta object with an active flag. I was ready to type the interface by hand and assume the second person would have the same keys as the first. That assumption is the useful part to check. The JSON converter at https://kepttools.com/json-converter reads the paste in the browser and drafts the interface from the first object only. The same text can also become a Laravel array, a PHP DTO, or CSV. The blocks below are that sample, run through the converter, not a tidied rewrite of it.

The Sample button uses this array:

[
  {"id": 1, "name": "Ada", "role": "engineer", "meta": {"active": true}},
  {"id": 2, "name": "Linus", "role": "founder", "meta": {"active": false}}
]
Enter fullscreen mode Exit fullscreen mode

Laravel keeps both people, and it keeps meta nested as a PHP array:

[
    [
        'id' => 1,
        'name' => 'Ada',
        'role' => 'engineer',
        'meta' => [
            'active' => true,
        ],
    ],
    [
        'id' => 2,
        'name' => 'Linus',
        'role' => 'founder',
        'meta' => [
            'active' => false,
        ],
    ],
]
Enter fullscreen mode Exit fullscreen mode

TypeScript stops at Ada. Linus never adds a field. Meta becomes its own interface because the value is an object:

export interface Root {
  id: number;
  name: string;
  role: string;
  meta: Meta;
}

export interface Meta {
  active: boolean;
}
Enter fullscreen mode Exit fullscreen mode

The PHP DTO is one class, always named DataTransferObject, and it is also Ada only. Meta is array, not a nested class:

<?php

declare(strict_types=1);

class DataTransferObject
{
    public int $id;
    public string $name;
    public string $role;
    public array $meta;

    public function __construct(array $data = [])
    {
        $this->id = $data['id'] ?? null;
        $this->name = $data['name'] ?? null;
        $this->role = $data['role'] ?? null;
        $this->meta = $data['meta'] ?? null;
    }
}
Enter fullscreen mode Exit fullscreen mode

CSV keeps the top-level keys and puts meta in a single cell. The nested object is JSON text, with quotes doubled:

id,name,role,meta
1,Ada,engineer,"{""active"":true}"
2,Linus,founder,"{""active"":false}"
Enter fullscreen mode Exit fullscreen mode

A shorter array makes the same cut obvious. [{"id":1,"name":"Ada"},{"id":2,"email":"linus@example.com"}] still becomes two Laravel rows, so email survives there. The interface and the PHP class keep id and name only. CSV's header is id,name,email: Ada's row ends on an empty cell, and the next row leaves name empty.

Two limits sit on top of that sample. If the root is an array, TypeScript and the PHP DTO never look past the first object, so a key that exists only later is missing from the draft. CSV does look at later rows when it builds the header, but a nested object still occupies one cell, not a new column per inner key. Invalid JSON clears the output and shows the parse error. { leaves the box empty with Expected property name or '}' in JSON at position 1 (line 1 column 2). An empty array is valid JSON and still not CSV: the output is cleared and the message is CSV conversion expects an array of objects.

One tip before you paste the draft into a project: open the second object and look for a key the first object does not have. Root will not list it. Add that field yourself, or convert a single object that already contains every key you mean to keep. The PHP constructor also assigns null when a key is absent, including into public int $id, so treat the class as a draft and rename DataTransferObject.

If the paste is hard to read, indent it first at https://kepttools.com/json-formatter and then convert. A trailing comma is enough to wipe the output.

Full guide with the FAQ and the converter: https://kepttools.com/guides/json-to-typescript-php-dto-laravel

Top comments (0)