Skip to content

Conversation

@risantos
Copy link

Description

This PR updates the no-undefined-types rule to support strict validation of TypeScript namespaces. Previously, the rule might have been too permissive or failed to recognize types defined within namespaces in the same file.

This became an issue recently with an update that led to definedTypes matching a declared namespace on a .d.ts file starting to report their inner properties/types/interfaces as undefined.

An example would be configuring the no-undefined-types with:

'jsdoc/no-undefined-types': ['error', { definedTypes: ['Foobar'] }],

while having a .d.ts file with something such as the following:

export type * as Foobiz from './foobiz';
export interface FoobarInterface {
  foo: string;
  bar: number;
}

export as namespace Foobar;

And then wanting to use Foobar.FoobarInterface, Foobar.FoobarInterface['foo'], or Foobar.Foobiz.biz as types on JSDoc. The TS LSP would recognize them, but this rule started reporting errors.

/**
 * @param {Foobar.FoobarInterface} foobarInterface - Foobar interface.
 * @returns {{ biz: Foobar.FoobarInterface['bar'], foo: Foobar.FoobarInterface['foo'] }} Biz and Foo.
 */
const functionOverFoobarInterface = foobarInterface => {
  const { bar, foo } = foobarInterface;

  return { biz: bar * 2, foo };
};

Changes

  • Strict Namespace Validation: Namespaces defined in the current file (TSModuleDeclaration) are now added to the closedTypes set. This means the rule will strictly validate members accessed on these namespaces (e.g., MyNamespace.NonExistentType will now be reported as undefined).
  • Recursive Type Discovery: The rule now recursively finds exported types within namespaces, including:
    • TSTypeAliasDeclaration.
    • TSInterfaceDeclaration (including their properties).
  • Test Updates:
    • Added test cases to verify valid access to defined namespace types and interfaces.
    • Added test cases to verify invalid access to undefined namespace types (strict validation).
    • Added a coverage test case to ensure ExportNamedDeclaration variants (like export class and export {}) are properly handled (ignored) without reducing code coverage.

- Adds `TSModuleDeclaration` to `closedTypes` to enforce strict validation of namespace members.
- Recursively finds exported types (`TSTypeAliasDeclaration`, `TSInterfaceDeclaration`) within namespaces.
- Adds support for interface properties within namespaces.
- Updates tests to verify strict validation of namespace members.
@brettz9 brettz9 force-pushed the fix/no-undefined-types/allow-namespace-types branch from ca41183 to ebe9ee0 Compare December 20, 2025 07:23
class MyClass {
method() {}
}
/** @type {MyClass.nonExistent} */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have the following examples based on class which pass in their access of a static property that does exist?

I.e., will your changes allow:

class MyClass {
}
MyClass.Existent = () => {};
/** @type {MyClass.Existent} */

and

class MyClass {
  static Existent = () => {};
}

/** @type {MyClass.Existent} */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants