Skip to content

Commit

Permalink
Avoid including defaulted type arguments
Browse files Browse the repository at this point in the history
Resolves #2820
  • Loading branch information
Gerrit0 committed Dec 25, 2024
1 parent b9177b4 commit 53fa22e
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
26 changes: 20 additions & 6 deletions src/lib/converter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -813,6 +813,7 @@ const referenceConverter: TypeConverter<
context,
name,
);

if (type.flags & ts.TypeFlags.Substitution) {
// NoInfer<T>
ref.typeArguments = [
Expand All @@ -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;
},
Expand Down
7 changes: 7 additions & 0 deletions src/lib/converter/utils/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
}
16 changes: 0 additions & 16 deletions src/test/converter/function/specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,6 @@
"name": "T",
"package": "typedoc",
"refersToTypeParameter": true
},
{
"type": "intrinsic",
"name": "any"
},
{
"type": "intrinsic",
"name": "any"
}
],
"name": "Iterable",
Expand Down Expand Up @@ -705,14 +697,6 @@
"name": "T",
"package": "typedoc",
"refersToTypeParameter": true
},
{
"type": "intrinsic",
"name": "any"
},
{
"type": "intrinsic",
"name": "any"
}
],
"name": "Iterable",
Expand Down
3 changes: 3 additions & 0 deletions src/test/converter2/issues/gh2820.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function f(a: Uint8Array): Uint8Array {
return a;
}
8 changes: 8 additions & 0 deletions src/test/issues.c2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
});
});

0 comments on commit 53fa22e

Please sign in to comment.