diff --git a/CHANGELOG.md b/CHANGELOG.md index a6d75277b..419b923a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ title: Changelog - `@include` and `@includeCode` now work in the readme file, #2814. - TypeDoc will now avoid making references to references, #2811. +- Improved type reference conversion to avoid including defaulted type arguments, #2820. - Improved link resolution logic to prioritize type alias properties with the same symbol over type literal properties within function parameters. diff --git a/src/lib/converter/types.ts b/src/lib/converter/types.ts index 3b9b91592..316e6e6ac 100644 --- a/src/lib/converter/types.ts +++ b/src/lib/converter/types.ts @@ -38,7 +38,7 @@ import { createSignature, } from "./factories/signature.js"; import { convertSymbol } from "./symbols.js"; -import { isObjectType } from "./utils/nodes.js"; +import { isObjectType, isTypeReference } from "./utils/nodes.js"; import { removeUndefined } from "./utils/reflections.js"; import type { TranslatedString } from "../internationalization/internationalization.js"; @@ -813,6 +813,7 @@ const referenceConverter: TypeConverter< context, name, ); + if (type.flags & ts.TypeFlags.Substitution) { // NoInfer ref.typeArguments = [ @@ -823,11 +824,24 @@ const referenceConverter: TypeConverter< convertType(context, (type as ts.StringMappingType).type), ]; } else { - ref.typeArguments = ( - type.aliasSymbol - ? type.aliasTypeArguments - : (type as ts.TypeReference).typeArguments - )?.map((ref) => convertType(context, ref)); + // Default type arguments are filled with a reference to the default + // type. As TS doesn't support specifying earlier defaults, we know + // that this will only filter out type arguments which aren't specified + // by the user. + let ignoredArgs: ts.Type[] | undefined; + if (isTypeReference(type)) { + ignoredArgs = type.target.typeParameters + ?.map((p) => p.getDefault()) + .filter((x) => !!x); + } + + const args = type.aliasSymbol + ? type.aliasTypeArguments + : (type as ts.TypeReference).typeArguments; + + ref.typeArguments = args + ?.filter((ref) => !ignoredArgs?.includes(ref)) + .map((ref) => convertType(context, ref)); } return ref; }, diff --git a/src/lib/converter/utils/nodes.ts b/src/lib/converter/utils/nodes.ts index 728a8f8ae..fa772404d 100644 --- a/src/lib/converter/utils/nodes.ts +++ b/src/lib/converter/utils/nodes.ts @@ -37,3 +37,10 @@ export function getHeritageTypes( export function isObjectType(type: ts.Type): type is ts.ObjectType { return typeof (type as any).objectFlags === "number"; } + +export function isTypeReference(type: ts.Type): type is ts.TypeReference { + return ( + isObjectType(type) && + (type.objectFlags & ts.ObjectFlags.Reference) !== 0 + ); +} diff --git a/src/test/converter/function/specs.json b/src/test/converter/function/specs.json index 52b4ad862..83146c961 100644 --- a/src/test/converter/function/specs.json +++ b/src/test/converter/function/specs.json @@ -547,14 +547,6 @@ "name": "T", "package": "typedoc", "refersToTypeParameter": true - }, - { - "type": "intrinsic", - "name": "any" - }, - { - "type": "intrinsic", - "name": "any" } ], "name": "Iterable", @@ -705,14 +697,6 @@ "name": "T", "package": "typedoc", "refersToTypeParameter": true - }, - { - "type": "intrinsic", - "name": "any" - }, - { - "type": "intrinsic", - "name": "any" } ], "name": "Iterable", diff --git a/src/test/converter2/issues/gh2820.ts b/src/test/converter2/issues/gh2820.ts new file mode 100644 index 000000000..e6e5d8abd --- /dev/null +++ b/src/test/converter2/issues/gh2820.ts @@ -0,0 +1,3 @@ +export function f(a: Uint8Array): Uint8Array { + return a; +} diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index c5bbfd76f..ba8935568 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -1983,4 +1983,12 @@ describe("Issue Tests", () => { ok(rename2.isReference()); ok(rename2.getTargetReflection() === abc); }); + + it("#2820 does not include defaulted type arguments", () => { + const project = convert(); + const f = querySig(project, "f"); + + equal(f.type?.toString(), "Uint8Array"); + equal(f.parameters?.[0].type?.toString(), "Uint8Array"); + }); });