vega / ts-json-schema-generator

Generate JSON schema from your Typescript sources
MIT License
1.38k stars 190 forks source link

Undefined reference in ObjectLiteralExpressionNodeParser when using typeof on a spread const #2012

Open samuelneff opened 1 week ago

samuelneff commented 1 week ago

This TypeScript definition generates an error in ObjectLiteralExpressionNodeParser.

npx ts-json-schema-generator --path './scratch42.ts' -e 'all'
export const a = {
  a: 'A'
};

export const b = {
  ...a,
  b: 'B'
};

export type A = typeof a;
export type B = typeof b;
.../ts-json-schema-generator/dist/ts-json-schema-generator.js:74
    throw error;
    ^

TypeError: Cannot read properties of undefined (reading 'getText')
    at .../ts-json-schema-generator/dist/src/NodeParser/ObjectLiteralExpressionNodeParser.js:17:97
    at Array.map (<anonymous>)
    at ObjectLiteralExpressionNodeParser.createType (.../ts-json-schema-generator/dist/src/NodeParser/ObjectLiteralExpressionNodeParser.js:17:44)
    at ChainNodeParser.createType (.../ts-json-schema-generator/dist/src/ChainNodeParser.js:30:45)
    at TypeofNodeParser.createType (.../ts-json-schema-generator/dist/src/NodeParser/TypeofNodeParser.js:45:45)
    at ChainNodeParser.createType (.../ts-json-schema-generator/dist/src/ChainNodeParser.js:30:45)
    at TypeOperatorNodeParser.createType (.../ts-json-schema-generator/dist/src/NodeParser/TypeOperatorNodeParser.js:22:43)
    at ChainNodeParser.createType (.../ts-json-schema-generator/dist/src/ChainNodeParser.js:30:45)
    at TypeAliasNodeParser.createType (.../ts-json-schema-generator/dist/src/NodeParser/TypeAliasNodeParser.js:36:43)
    at AnnotatedNodeParser.createType (.../ts-json-schema-generator/dist/src/NodeParser/AnnotatedNodeParser.js:29:47)

This is the line of code that errors (whitespace added):

// ObjectLiteralExpressionNodeParser line 17
const properties = node.properties.map(
  (t) => new ObjectType_js_1.ObjectProperty(
    t.name.getText(),                             //   <-- ERROR HERE
    this.childNodeParser.createType(
      t.initializer,
      context
    ),
    !t.questionToken
  )
);

The error is on t.name.getText() because t.name is undefined.

I can work around the error by adding an explicit type declaration to b, but TypeScript itself understands the declarations without it.

export const a = {
  a: 'A'
};

// Workaround here
export const b: typeof a & {b: 'B'} = {
  ...a,
  b: 'B'
};

export type A = typeof a;
export type B = typeof b;
node v20.13.1
npm v10.5.2
ts-json-schema-generator v2.3.0
typescript v5.5.3