typedoc icon indicating copy to clipboard operation
typedoc copied to clipboard

TypeDoc exiting with unexpected error: intersectionConverter.convertType missing map

Open apowers313 opened this issue 3 years ago • 2 comments

Search terms

  • TypeError: Cannot read properties of undefined (reading 'map')
  • intersectionConverter
  • convertType
  • undefined map

Expected Behavior

Expected that typing typedoc from the CLI would generate documentation.

Actual Behavior

typedoc with this config throws the following error:

TypeDoc exiting with unexpected error: TypeError: Cannot read properties of undefined (reading 'map') at Object.convertType (/Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:250:57) at convertType (/Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:96:34) at /Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:250:71 at Array.map () at Object.convertType (/Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:250:57) at convertType (/Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:96:34) at /Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:404:109 at Array.map () at Object.convertType (/Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:404:96) at convertType (/Users/ampower/Projects/personal/dataflow/node_modules/typedoc/dist/lib/converter/types.js:96:34)

The error seems to be related Readable.ts file which implements the TypeScript mixin pattern. Looking at the thrown error, it seems that intersectionConverter.convertType() chokes that types doesn't contain a map. I don't see anything particularly esoteric about the types in the file that would lead to this.

Steps to reproduce the bug

Still working on a minimal reproduction. Will post when I manage to pull apart the code and still reproduce the bug.

Environment

  • Typedoc version: 0.23.8
  • TypeScript version: 4.7.4
  • Node.js version: v17.4.0
  • OS: MacOS Monterey 12.3.1

apowers313 avatar Jul 21 '22 18:07 apowers313

Huh, that's an odd bug. Mixins do do really horrible things in the type system though...

Gerrit0 avatar Jul 21 '22 23:07 Gerrit0

Minimal repro:

export class Component {}

type Constructor<T = Record<any, any>> = new (... args: any[]) => T;

export function Readable<TBase extends Constructor<Component>>(Base: TBase) {
    abstract class Reader extends Base {}
    return Reader
}

TypeDoc handles this perfectly fine if the Reader class is not abstract. Once it's abstract, TypeScript changes the return type stringification:

type A = { new (...args: any[]): Reader; prototype: Readable<any>.Reader; } & TBase
type B = ((abstract new (...args: any[]) => Reader) & { prototype: Readable<any>.Reader; }) & TBase

In both of these cases, this is an intersection with two members, and the first member of the intersection is an object type, not an intersection type. This is because { abstract new (...args: any[]) => Reader } is not a valid type, since abstract cannot appear on type members.

Since TypeDoc uses typeToTypeNode (same function that the typeToString method uses) to get a type kind that can be mapped into a converter, this first member is then detected as an intersection, even though it isn't, and 💥

Adding this in the convertType fixes things... I really dislike it though

if (!type.isIntersection()) return typeLiteralConverter.convertType(context, type);

Gerrit0 avatar Jul 23 '22 22:07 Gerrit0

Same error in idea2app/MobX-RESTful#5

TechQuery avatar Aug 18 '22 17:08 TechQuery

Thank you for fixing this :)

apowers313 avatar Aug 27 '22 00:08 apowers313