Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: (?) Incorrect union when literals overlap #2667

Open
t1mp4 opened this issue Dec 6, 2024 · 0 comments
Open

[BUG]: (?) Incorrect union when literals overlap #2667

t1mp4 opened this issue Dec 6, 2024 · 0 comments
Labels

Comments

@t1mp4
Copy link

t1mp4 commented Dec 6, 2024

Issue Type

Quicktype output

Context (Environment, Version, Language)

  • Input format: JSON
  • Target language: TypeScript
  • Quicktype version: 23.0.170
  • Quicktype usage: CLI

Description

I have JSON files containing NHL roster data. Each player object has a positionCode property and a shootsCatches property:

  • The positionCode property can be one of "L", "C", "R", "D", or "G".
  • The shootsCatches property can only be "L" or "R".

It's important to note here that "L" and "R" overlap between these two properties.

When I convert the JSON to TypeScript using Quicktype, the resulting type for the positionCode property is:

export type PositionCode = "L" | "C" | "R" | "D" | "G";

This part is correct, as it reflects all possible values for positionCode. However, Quicktype incorrectly assigns the same union type to the shootsCatches property, which should only allow "L" or "R".

Input Data

To generate the input data:

  1. Create a folder called json inside the root of a Node.js project.
  2. Run this script from the project root:
import fs from "fs";
import path from "path";

const SAMPLES = 50;
const PLAYERS_PER_TEAM = 30;

const POSITION_CODES = ["L", "C", "R", "D", "G"];
const SHOOTS_CATCHES = ["L", "R"];

const basePath = path.join(process.cwd(), "json");

for (let sample = 0; sample < SAMPLES; sample++) {
  const players = [];

  for (let player = 0; player < PLAYERS_PER_TEAM; player++) {
    players.push({
      positionCode: POSITION_CODES[player % POSITION_CODES.length],
      shootsCatches: SHOOTS_CATCHES[player % SHOOTS_CATCHES.length],
    });
  }

  fs.writeFileSync(
    path.join(basePath, `${sample}.json`),
    JSON.stringify({
      players,
    })
  );
}

Command to generate output

quicktype json/*.json --top-level Root --lang typescript --just-types --prefer-types --prefer-const-values --prefer-unions -o generated-types.ts

Expected Behaviour / Output

I expect positionCode and shootsCatches to be seperate union types.

export type Root = {
    players: Player[];
}

export type Player = {
    positionCode:  PositionCode;
    shootsCatches: ShootsCatches;
}

export type PositionCode = "L" | "C" | "R" | "D" | "G";

export type ShootsCatches = "L" | "R";

Current Behaviour / Output

export type Root = {
    players: Player[];
}

export type Player = {
    positionCode:  PositionCode;
    shootsCatches: PositionCode;
}

export type PositionCode = "L" | "C" | "R" | "D" | "G";
@t1mp4 t1mp4 added the bug label Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant