ts-json-schema-generator icon indicating copy to clipboard operation
ts-json-schema-generator copied to clipboard

Unexpected type for enum

Open water-a opened this issue 4 years ago • 6 comments

Not exactly sure why this is erroring...but I assume it has something to do with the generics:

test.ts

enum Module {
  A = 'A',
  B = 'B',
}

interface AOptions {
  name: string;
  quantity: number;
}

interface BOptions {
  name: string;
  color: string;
}

interface OptionsMap {
  [Module.A]: Pick<AOptions, 'quantity'>;
  [Module.B]: Pick<BOptions, 'color'>;
}

type Options<T = Module> = T extends Module ? OptionsMap[T] : null;

export interface Store {
  options: Options;
}

command npx ts-json-schema-generator --path ./test.ts --type "Store"

water-a avatar Nov 17 '20 20:11 water-a

What exactly is the error? Would you have time to dig into it and send a pull request to fix it?

domoritz avatar Nov 17 '20 20:11 domoritz

Oh my bad for not including it.

Error: Unexpected type "enum-test.ts-0-37-test.ts-0-379" (expected "LiteralType" or "StringType" or "NumberType")

water-a avatar Nov 17 '20 20:11 water-a

https://github.com/vega/ts-json-schema-generator/blob/master/src/NodeParser/IndexedAccessTypeNodeParser.ts

Looks like there's an issue with this...so it's similar to #171 #170

water-a avatar Nov 17 '20 20:11 water-a

I see. To fix this, try to reduce the example to the minimum that reproduces it, then step through the code with a debugger while running the example and fix the code. Then put the minimal example into a new test case.

https://github.com/vega/ts-json-schema-generator/pull/170/files is a good example of a great patch.

domoritz avatar Nov 17 '20 20:11 domoritz

Example

enum Enum {
    bar,
}
const foo = {
    [Enum.bar]: "foobar",
};
export type MyType = typeof foo[Enum.bar];

So I'm trying to fix to fix this issue, but I'm running into an issue with the parsed index type of the object we're accessing:

index type for the object we're accessing

ObjectProperty {
  name: '[Enum.bar]',
  type: LiteralType { value: 'foobar' },
  required: true,
}

index type we're trying to access the object with

EnumType {
      id: 'enum-1660573991-11-19-1660573991-0-22-1660573991-0-109',
      values: [ 0 ],
    types: [ LiteralType { value: 0 } ]
}

There's no way for me to compare the ObjectProperty and EnumType in terms of the actual value of the enum.

I've attempted to make a fix to the original problem by just comparing the names of the ObjectProperty and Enum. I added a name property to EnumType and set it to be either the enum's name (ex: "Enum") if it's a Enum declaration or the enum value's name (ex: "Enum.bar") if it's a Enum member. Then I compared this with the ObjectProperty's name.

However, I think this is a bad fix as we're not actually computing the value of the enum and comparing the values to each other. I do not have more time to dedicate to fixing this issue.

I've left a "fix" here: https://github.com/water-a/ts-json-schema-generator/commit/5eedadd6e3b8e1680bb15c9491b7cc654372a23f

water-a avatar Nov 17 '20 22:11 water-a

Thanks for writing up your approach.

I would have to dive deeper into this but I think the typescript compiler can give you access to the actual values somehow. I'll leave this issue open for anyone who wants to continue the exploration.

domoritz avatar Nov 17 '20 23:11 domoritz