rushstack icon indicating copy to clipboard operation
rushstack copied to clipboard

[api-extractor] Error caused by using the same name for an interface and namespace

Open akshay-madhukar opened this issue 6 years ago • 6 comments

When an interface and a namespace have the same name as shown by TestName in this sample .d.ts file

interface TestName {
    type: number;
    index: number;
    size: number;
}

export declare namespace TestName {
    function createDefault(): TestName;
}

export { default as Log } from './log/Log';

the following error is seen in v7.0.18

Error: Internal Error: _notifyReferencedAstEntity() called after analysis is already complete
You have encountered a software defect. Please consider reporting the issue to the maintainers of this application.

However, if the last export is omitted, and only the interface and namespace are included, the api-extractor runs with no issues. There must be at least one additional export for the error to appear.

akshay-madhukar avatar Feb 22 '19 20:02 akshay-madhukar

Which release of API Extractor are you using?

octogonz avatar Feb 22 '19 22:02 octogonz

I am using 7.0.18

akshay-madhukar avatar Feb 22 '19 22:02 akshay-madhukar

I confirmed that this is a bug. Thanks for providing the repro.

octogonz avatar Mar 13 '19 04:03 octogonz

@akshay-madhukar The inconsistency arises because namespace TestName is exported but interface TestName is not. I actually didn't know this was even allowed in TypeScript. In most cases you would get this error:

(TS2395) Individual declarations in merged declaration '__' must be all exported or all local.

I guess interfaces are special because they don't correspond to an actual JavaScript object, so the export is only conceptual.

This is an API Extractor bug, and we should fix it. But in the meantime as a workaround you can export the interface.

If the interface is supposed to be private, very soon I'm going to implement https://github.com/Microsoft/web-build-tools/issues/972 which will allow you to mark it as @internal while marking the namespace as @public.

octogonz avatar Mar 13 '19 04:03 octogonz

It seems that api-extractor doesn't have any error anymore with an interface and namespace merged declaration, but api-documenter doesn't seem to generate the documentation properly.

export declare namespace Test {
    export type Kind = string;

    /**
     * Create a {@link (Test:interface)} of the given kind
     *
     * @param kind - The {@link (Test:namespace).Kind | kind} of the test.
     */
    export function create(kind: Kind): Test;
}

/**
 * A Test
 *
 * @public
 */
export interface Test {
    kind: Test.Kind;
}

Will not generate any documentation for the interface.

The following warnings are also produced:

WARNING: Unable to resolve reference "(Test:interface)": The member reference "Test" was ambiguous
WARNING: Unable to resolve reference "(Test:namespace).Kind": The member reference "Test" was ambiguous
WARNING: Unable to resolve reference "(Test:interface)": The member reference "Test" was ambiguous

mhofman avatar May 29 '19 23:05 mhofman

This issue belongs to a family of closely related issues. I've created metaissue #1308 to come up with a unified fix that tackles them all together.

octogonz avatar Jun 02 '19 20:06 octogonz