`node.getDefinitionNodes()` fails to find anonymous default exported function or class.
- Dominant language
- TypeScript
- Stars
- 6.2k
- Forks
- 238
- Avg merge
- 2m
- Merged PRs (30d)
- 1
Description
**Describe the bug**
Calling `node.getDefinitionNodes()` on an identifier node who's corresponding definition is a default exported anonymous function or class returns an empty array. It should instead return the declaration node as it does if the class or function is anonymous.
When calling `node.getDefinitions()` it returns an array with a single `DefinitionInfo` node so the issue appears to exist in `getDefinitionNodes` implementation. (`getDefinitions` is from typescript `getDefinitionNodes` is from ts-morph).
Version: 15.1.0
**To Reproduce**
```ts
import { Project } from "ts-morph";
const project = new Project();
const sourceFile = project.createSourceFile("fileWithDefaultUnamed.ts", `export default function() {}`);
const sourceFile2 = project.createSourceFile("test.ts", `import unnamedFn from "./fileWithDefaultUnamed.ts";
unnamedFn()`);
const callExpr = sourceFile2.getFirstDescendantByKind(SyntaxKind.CallExpression);
// The following will return an empty array
const definitionNodes = callExpr?.getExpressionIfKind(SyntaxKind.Identifier)?.getDefinitionNodes();
// The following will return an array with a single entry
const definitions = callExpr?.getExpressionIfKind(SyntaxKind.Identifier)?.getDefinitions();
```
A similar example can be cooked up for a unnamed class.
**Expected behavior**
It should instead return the declaration node as it does if the class or function was named.
**Possible solution**
The problem appears to be in the implementation of [`getDefinitionNodes`](https://github.com/dsherret/ts-morph/blob/cea07aa7759ecf5a1e9f90b628334b8bd617c624/packages/ts-morph/src/compiler/tools/results/DefinitionInfo.ts#L52) as it looks for matching identifier node which won't exist since the declaration doesn't have an identifier due to being anonymous.
I have got around this myself by doing the following instead of `node.getDefinitionNodes()`:
```ts
const definitions = node.getDefinitions();
const definitionNodes = definitions
.map((d) => d.getNode().getParent())
.filter(isNotUndefined);
```
Not sure if there are cases where this won't work but it seems like it should work. Could the implementation linked above be changed to this method?
Contributor guide
Research direction
Start in packages/ts-morph/src/compiler/tools/results/DefinitionInfo.ts, at the getDefinitionNodes implementation linked in the issue. Compare its handling with getDefinitions and use the provided default-exported anonymous function reproduction as the first case to inspect. Done means getDefinitionNodes returns the declaration node for anonymous default-exported functions and classes, matching the expected behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100