Skip to content

Commit

Permalink
Handle @template constraints correctly
Browse files Browse the repository at this point in the history
Resolves #2389
  • Loading branch information
Gerrit0 committed Oct 8, 2023
1 parent 8e0aaf7 commit 130ba48
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

### Bug Fixes

- Fixed conversion of `@template` constraints on JSDoc defined type parameters, #2389.
- Invalid link validation is now correctly suppressed before all projects have been converted in packages mode, #2403.
- Fixed tsconfig handling for projects using a solution-style tsconfig, #2406.
- Fixed broken settings icons caused by icon caching introduced in 0.25.1, #2408.
Expand Down
48 changes: 48 additions & 0 deletions src/lib/converter/factories/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,54 @@ export function createTypeParamReflection(
return paramRefl;
}

export function convertTemplateParameterNodes(
context: Context,
nodes: readonly ts.JSDocTemplateTag[] | undefined,
) {
return nodes?.flatMap((node) => {
return node.typeParameters.map((param, index) => {
const paramRefl = new TypeParameterReflection(
param.name.text,
context.scope,
getVariance(param.modifiers),
);
const paramScope = context.withScope(paramRefl);
paramRefl.type =
index || !node.constraint
? void 0
: context.converter.convertType(
paramScope,
node.constraint.type,
);
paramRefl.default = param.default
? context.converter.convertType(paramScope, param.default)
: void 0;
if (
param.modifiers?.some(
(m) => m.kind === ts.SyntaxKind.ConstKeyword,
)
) {
paramRefl.flags.setFlag(ReflectionFlag.Const, true);
}

context.registerReflection(paramRefl, param.symbol);

if (ts.isJSDocTemplateTag(param.parent)) {
paramRefl.comment = context.getJsDocComment(param.parent);
}

context.trigger(
ConverterEvents.CREATE_TYPE_PARAMETER,
paramRefl,
param,
);
return paramRefl;
});
});
const params = (nodes ?? []).flatMap((tag) => tag.typeParameters);
return convertTypeParameterNodes(context, params);
}

function getVariance(
modifiers: ts.ModifiersArray | undefined,
): VarianceModifier | undefined {
Expand Down
10 changes: 1 addition & 9 deletions src/lib/converter/jsdoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { Context } from "./context";
import { ConverterEvents } from "./converter-events";
import {
convertParameterNodes,
convertTypeParameterNodes,
convertTemplateParameterNodes,
} from "./factories/signature";

export function convertJsDocAlias(
Expand Down Expand Up @@ -163,14 +163,6 @@ function convertTemplateParameters(context: Context, node: ts.JSDoc) {
);
}

function convertTemplateParameterNodes(
context: Context,
nodes: readonly ts.JSDocTemplateTag[] | undefined,
) {
const params = (nodes ?? []).flatMap((tag) => tag.typeParameters);
return convertTypeParameterNodes(context, params);
}

function getTypedefReExportTarget(
context: Context,
declaration: ts.JSDocTypedefTag | ts.JSDocEnumTag,
Expand Down
6 changes: 6 additions & 0 deletions src/test/converter2/issues/gh2389.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @template {string} T, U
* @param {T} x
* @param {U} y
*/
export function foo(x, y) {}
11 changes: 11 additions & 0 deletions src/test/issues.c2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,17 @@ describe("Issue Tests", () => {
);
});

it("Handles @template parameter constraints correctly, #2389", () => {
const project = convert();
const foo = query(project, "foo");
equal(foo.signatures?.length, 1);
equal(foo.signatures[0].typeParameters?.length, 2);

const [T, U] = foo.signatures[0].typeParameters;
equal(T.type?.toString(), "string");
equal(U.type?.toString(), undefined);
});

// This is rather unfortunate, we need to do this so that files which include only
// a single declare module can still have a comment on them, but it looks really
// weird and wrong if there are multiple declare module statements in a file...
Expand Down

0 comments on commit 130ba48

Please sign in to comment.