quicktype icon indicating copy to clipboard operation
quicktype copied to clipboard

JSON -> TypeScript (array of items & root-level interface issues)

Open artdevgame opened this issue 4 years ago • 4 comments

Hello 👋🏻

With this data:

[
  { "name": "fly_one_cm", "value": "2.46 m" },
  { "name": "damage_blocked_by_shield", "value": 0 },
  { "name": "raid_win", "value": 0 },
  { "name": "fill_cauldron", "value": 0 },
  { "name": "open_enderchest", "value": 0 },
  { "name": "open_barrel", "value": 0 },
  { "name": "damage_taken", "value": 0 },
  { "name": "player_kills", "value": 0 },
  { "name": "time_since_rest", "value": "16.1233 min" }
]

I get the following result:

export interface MatchInfoGeneralStats {
    name:  string;
    value: number | string;
}

This can be reproduced on: https://app.quicktype.io/

However, what I'm expecting to receive after transformation is an array of types, something like:

export type MatchInfoGeneralStats = [{
    name:  string;
    value: number | string;
}]

Are there any options to generate this output that I'm missing?

I'm using the library like this:

const { lines: schema } = await quicktype({ inputData, lang: 'typescript', rendererOptions: { 'just-types': 'true' } });
console.log(schema.join('\n'));

artdevgame avatar Feb 06 '22 15:02 artdevgame

Here's another example that produces the wrong (no) output:

{
  "Score": 0,
  "RoundsWon": 0,
  "RoundsTied": 0,
  "PersonalScore": 50,
  "Kills": 0,
  "Deaths": 4,
  "Assists": 1,
  "KDA": 0,
  "Suicides": 0,
  "Betrayals": 0,
  "AverageLifeDuration": 0,
  "BestKillingSpree": 0,
  "Headshots": 0,
  "ShotsFired": 0,
  "ShotsHit": 0,
  "AccuracyPercentage": 0,
  "MeleeKills": 0,
  "GrenadeKills": 0,
  "PowerWeaponKills": 0,
  "DamageDone": 0,
  "DamageTaken": 0
}

In this example, I would expect an interface to be returned:

{
  Score: number;
  RoundsWon: number;
  RoundsTied: number;
  PersonalScore: number;
  Kills: number;
  Deaths: number;
  Assists: number;
  KDA: number;
  Suicides: number;
  Betrayals: number;
  AverageLifeDuration: number;
  BestKillingSpree: number;
  Headshots: number;
  ShotsFired: number;
  ShotsHit: number;
  AccuracyPercentage: number;
  MeleeKills: number;
  GrenadeKills: number;
  PowerWeaponKills: number;
  DamageDone: number;
  DamageTaken: number;
}

Or, a Record type:

export type MatchInfoGeneralStats = Record<string, number>

I'm not sure if I'm misunderstanding how to use the tool, or if there's just limitations to it that I'm hitting?

artdevgame avatar Feb 06 '22 15:02 artdevgame

Up, i am affected by this.

gaelmotte avatar Mar 29 '23 09:03 gaelmotte

Getting the same issue as described in the initial comment. My api responses come as an array, however, quicktype seems to be ignoring this and generating the interface for the elements of the array only. Is there an option to configure or a workaround for this? Thanks

curtisburns avatar Apr 17 '23 22:04 curtisburns

I have encountered the same problem. So far, I haven't found an option to help me generate array types. I can only manually judge whether it is an array, and then insert some custom codes.

export const json2typescript = async (json: string, name: string = 'Data') => {
  let isArray = false;

  try {
    isArray = Array.isArray(JSON.parse(json));
  } catch (err) {
    throw new Error(String(err));
  }

  const jsonInput = jsonInputForTargetLanguage('typescript');
  await jsonInput.addSource({
    name,
    samples: [json]
  });

  const inputData = new InputData();
  inputData.addInput(jsonInput);
  const { lines } = await quicktype({
    inputData,
    lang: 'typescript',
    rendererOptions: {
      'just-types': true
    },
    indentation: '  '
  });
  let tsCode = lines.join('\n');
  if (isArray) {
    tsCode = `export type ${name}List = ${name}[];\n` + tsCode;
  }

  return tsCode;
};

hacxy avatar Oct 26 '24 01:10 hacxy