quicktype icon indicating copy to clipboard operation
quicktype copied to clipboard

[FEATURE]: Discriminant types

Open MARCROCK22 opened this issue 7 months ago • 0 comments

Possibility of specifying some "properties" so the type can be segmented and can be more accurate.

Context (Input, Language)

Input format: json Output format: typescript

Description

This will help to create more accurate types and less "mixed" types. Normally with "complex" types such as below, before this feature, the types generated will have a lot of optional properties or mixed types.

Current Behaviour / Output

Can't specify the "unique" properties, so you get a mixed type that doesn't really represents the real object

export interface Segment {
    readonly type:         string;
    readonly name:         string;
    readonly customer_id?: number | null;
    readonly permissions?: string;
}
export interface Segment {
    readonly data: Datum[];
}

export interface Datum {
    readonly type:         string;
    readonly name:         string;
    readonly customer_id?: number | null;
    readonly permissions?: string;
}

Proposed Behaviour / Output

Input:

[{
    "type": "admin",
    "name": "SuperAdmin",
    "customer_id": null
}, {
    "type": "user",
    "name": "Fabrizio",
    "customer_id": 1
}, {
    "type": "role",
    "name": "ultra_admin",
    "permissions": "1234"
}]
{
  "data": [{
    "type": "admin",
    "name": "SuperAdmin",
    "customer_id": null
  }, {
    "type": "user",
    "name": "Fabrizio",
    "customer_id": 1
  }, {
    "type": "role",
    "name": "ultra_admin",
    "permissions": "1234"
  }]
}

Output:

export interface AdminSegment {
  type: "admin";
  name: string;
  customer_id: null;
}

export interface UserSegment {
  type: "user";
  name: string;
  customer_id: number;
}

export interface RoleSegment {
  type: "role";
  name: string;
  permissions: string;
}

export type Segment = AdminSegment | UserSegment | RoleSegment;
export interface AdminDatum {
  type: "admin";
  name: string;
  customer_id: null;
}

export interface UserDatum {
  type: "user";
  name: string;
  customer_id: number;
}

export interface RoleDatum {
  type: "role";
  name: string;
  permissions: string;
}

export type Datum = AdminDatum | UserDatum | RoleDatum;

export interface Segment {
  data: Datum[];
}

Solution

A render option such as discriminantKeys: ["$.type", "$.data[].type"]

Alternatives

Typing the type manually.

Context

MARCROCK22 avatar Feb 28 '25 18:02 MARCROCK22