Skip to content

TypeDoc expands very complex type aliases instead of referring to them #1867

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

Closed
Mirdukkk opened this issue Feb 9, 2022 · 3 comments
Closed

Comments

@Mirdukkk
Copy link

Mirdukkk commented Feb 9, 2022

Problem

When TypeDoc generates documentation in JSON, bumping into complex object/template literal types, it takes them apart piece by piece, instead of creating a reference type.

Actual Behavior

TypeDoc creates a huge union type, parsing type alias into all its possible values:
image

At the same time, the type to which it should refer is declared correctly and exported:
image

And this type declaration works file:

"type": {
	"type": "template-literal",
	"head": "",
	"tail": [
		[
			{
				"type": "query",
				"queryType": {
					"type": "reference",
					"id": 5940,
					"name": "CACHE_POINTER_PREFIX"
				}
			},
			":"
		],
		[
			{
				"type": "reference",
				"id": 5950,
				"name": "Keyspaces"
			},
			":"
		],
		[
			{
				"type": "reference",
				"qualifiedName": "CacheStorageKey",
				"package": "@discordoo/providers",
				"name": "CacheStorageKey"
			},
			":"
		],
		[
			{
				"type": "intrinsic",
				"name": "string"
			},
			""
		]
	]
}

As a result, the documentation looks like this:
image

Expected Behavior

But the documentation is expected to look like this:
image

TypeDoc was expected to create a reference to the type:

"type": {
	"type": "union",
	"types": [
		{
			"type": "reference",
			"id": 4869,
			"name": "CachePointer"
		},
		{
			"type": "reference",
			"id": 4681,
			"name": "V"
		}
	]
}

Steps to reproduce the bug

Reproduction repo: https://github.com/Mirdukkk/typedoc-issue

  1. Create any complex type, such as an object:
// types.ts
const something = 'something' 

export const SOME_CONST = {
  valuenum1: something,
  valuenum2: something,
  valuenum3: something,
  valuenum4: something,
  valuenum5: something,
  valuenum6: something,
  valuenum7: something,
  valuenum8: something,
  valuenum9: something,
  valuenum10: something,
  valuenum11: something,
}

export type SomeConstType = typeof SOME_CONST // this type will cause problem
  1. Use it in absolutely any place where Type Doc can document it:
// work.ts
import { SomeConstType, SOME_CONST } from './types'

export function doSomething<K extends keyof SomeConstType>(key: K): SomeConstType[K] {
  return SOME_CONST[key]
}
  1. Don't forget to export it all so that typedoc has the opportunity to document it:
// index.ts
export { SomeConstType } from './types'
export { doSomething } from './work'
  1. Document it with json output:
npx typedoc index.ts --json docs.json
  1. You will see that in the declaration of the return type of the doSomething function, there is a huge union type, instead of the reference type.

Don't forget to put any tsconfig that would compile three files: index.ts, work.ts and types.ts.

See also

perhaps the bug reason is here: #1258 (comment)

Environment

  • Typedoc version: 0.22.11
  • TypeScript version: 4.5.5
  • Node.js version: tested on 12.20.0/16.6.0/17.1.0 with the same result
  • OS: Win32 19043.1415 / Linux 4.4.0-19041-Microsoft 1237-Microsoft Sat Sep 11 14:32:00 PST 2021 x86_64 x86_64 x86_64 GNU/Linux (Windows WSL Ubuntu 20.04)

Search terms

type aliases
expands
reffer

@Gerrit0
Copy link
Collaborator

Gerrit0 commented Feb 10, 2022

This is a design limitation right now - TypeDoc relies on TypeScript to determine what type it should display when dealing with generics. Since TypeScript (since TS 4.2) preserves the alias name if the object type was created in type space, rather than with a type query type, this is likely a bug/missed edge case in the improvements for smarter type alias preservation. I've opened microsoft/TypeScript#47828 to track that.

class Generic<T> {
  method(): T extends string ? 123 : 456
}

// Child.method should be documented as returning 123, not 
// "T extends string ? 123 : 456" or "string extends string ? 123 : 456"
// Implementing this without re-implementing the whole type checker means relying on TS.
class Child extends Generic<string> {}

If you hover over the function signature, you'll see the same display as what TypeDoc renders.

@Mirdukkk
Copy link
Author

I also ran tests on different versions of TypeScript, and the result was the same. Let me know if it turns out to be useful: https://github.com/Mirdukkk/typedoc-issue (docs-ts-*.json)

@Gerrit0
Copy link
Collaborator

Gerrit0 commented Feb 12, 2022

This is unfortunately something that can't really be fixed in TypeDoc. microsoft/TypeScript#47828 needs to happen, and once it does TypeDoc will automatically pick up the change

@Gerrit0 Gerrit0 closed this as completed Feb 19, 2022
@Gerrit0 Gerrit0 removed the bug label Feb 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants