Skip to content

Commit c9103fc

Browse files
committed
Improve handling of function-modules created with Object.assign
Resolves #2436
1 parent c86f4a9 commit c9103fc

File tree

5 files changed

+61
-13
lines changed

5 files changed

+61
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Fixed default option values on options declared by plugins in packages mode, #2433.
66
- `gitRevision` will now be replaced in `sourceLinkTemplate`, #2434.
7+
- Improved handling of function-modules created with `Object.assign`, #2436.
78
- Fixed an infinite loop when `skipLibCheck` is used to ignore some compiler errors, #2438.
89

910
### Thanks!

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"test": "mocha --config .config/mocha.fast.json",
6565
"test:cov": "c8 mocha --config .config/mocha.fast.json",
6666
"doc:c": "node bin/typedoc --tsconfig src/test/converter/tsconfig.json",
67-
"doc:c2": "node --inspect-brk bin/typedoc --tsconfig src/test/converter2/tsconfig.json",
67+
"doc:c2": "node bin/typedoc --tsconfig src/test/converter2/tsconfig.json",
6868
"test:full": "c8 mocha --config .config/mocha.full.json",
6969
"test:visual": "ts-node ./src/test/capture-screenshots.ts && ./scripts/compare_screenshots.sh",
7070
"test:visual:accept": "node scripts/accept_visual_regression.js",

src/lib/converter/symbols.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -178,18 +178,6 @@ export function convertSymbol(
178178
flags = removeFlag(flags, ts.SymbolFlags.Property);
179179
}
180180

181-
// A default exported function with no associated variable is a property, but
182-
// we should really convert it as a variable for documentation purposes
183-
// export default () => {}
184-
// export default 123
185-
if (
186-
flags === ts.SymbolFlags.Property &&
187-
symbol.name === "default" &&
188-
context.scope.kindOf(ReflectionKind.Module | ReflectionKind.Project)
189-
) {
190-
flags = ts.SymbolFlags.BlockScopedVariable;
191-
}
192-
193181
for (const flag of getEnumFlags(flags ^ allConverterFlags)) {
194182
if (!(flag & allConverterFlags)) {
195183
context.logger.verbose(
@@ -645,6 +633,14 @@ function convertProperty(
645633
symbol: ts.Symbol,
646634
exportSymbol?: ts.Symbol,
647635
) {
636+
// This might happen if we're converting a function-module created with Object.assign
637+
// or `export default () => {}`
638+
if (
639+
context.scope.kindOf(ReflectionKind.SomeModule | ReflectionKind.Project)
640+
) {
641+
return convertVariable(context, symbol, exportSymbol);
642+
}
643+
648644
const declarations = symbol.getDeclarations() ?? [];
649645

650646
// Don't do anything if we inherited this property and it is private.
@@ -1019,6 +1015,24 @@ function convertVariableAsFunction(
10191015
);
10201016
}
10211017

1018+
// #2436: Functions created with Object.assign on a function won't have a namespace flag
1019+
// but likely have properties that we should put into a namespace.
1020+
if (
1021+
type.getProperties().length &&
1022+
!hasAnyFlag(
1023+
symbol.flags,
1024+
ts.SymbolFlags.NamespaceModule | ts.SymbolFlags.ValueModule,
1025+
)
1026+
) {
1027+
const ns = context.createDeclarationReflection(
1028+
ReflectionKind.Namespace,
1029+
symbol,
1030+
exportSymbol,
1031+
);
1032+
context.finalizeDeclarationReflection(ns);
1033+
convertSymbols(context.withScope(ns), type.getProperties());
1034+
}
1035+
10221036
return ts.SymbolFlags.Property;
10231037
}
10241038

src/test/converter2/issues/gh2436.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/** The FOO function */
2+
function foo() {
3+
return "foo";
4+
}
5+
6+
function bugInner(): { foo: string } {
7+
return { foo: "bar" };
8+
}
9+
10+
export const bug: {
11+
(): { foo: string };
12+
foo: typeof foo;
13+
bar: 42;
14+
} = Object.assign(bugInner, {
15+
foo,
16+
bar: 42 as const,
17+
});

src/test/issues.c2.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,22 @@ describe("Issue Tests", () => {
11971197
);
11981198
});
11991199

1200+
it("Handles function-namespaces created with Object.assign #2436", () => {
1201+
const project = convert();
1202+
equal(project.children?.map((c) => c.kind), [
1203+
ReflectionKind.Namespace,
1204+
ReflectionKind.Function,
1205+
]);
1206+
equal(
1207+
project.children[0].getChildByName("bar")?.kind,
1208+
ReflectionKind.Variable,
1209+
);
1210+
equal(
1211+
project.children[0].getChildByName("foo")?.kind,
1212+
ReflectionKind.Function,
1213+
);
1214+
});
1215+
12001216
it("Handles recursive aliases without looping infinitely #2438", () => {
12011217
const bad = query(convert(), "Bad");
12021218
equal(bad.kind, ReflectionKind.Interface);

0 commit comments

Comments
 (0)