diff --git a/apps/api-extractor/src/analyzer/ExportAnalyzer.ts b/apps/api-extractor/src/analyzer/ExportAnalyzer.ts index 7ac791ea39a..6400c1bc470 100644 --- a/apps/api-extractor/src/analyzer/ExportAnalyzer.ts +++ b/apps/api-extractor/src/analyzer/ExportAnalyzer.ts @@ -348,6 +348,17 @@ export class ExportAnalyzer { symbol: ts.Symbol, referringModuleIsExternal: boolean ): AstEntity | undefined { + // eslint-disable-next-line no-bitwise + if ((symbol.flags & ts.SymbolFlags.FunctionScopedVariable) !== 0) { + // If a symbol refers back to part of its own definition, don't follow that rabbit hole + // Example: + // + // function f(x: number): typeof x { + // return 123; + // } + return undefined; + } + let current: ts.Symbol = symbol; if (referringModuleIsExternal) { diff --git a/build-tests/api-extractor-scenarios/config/build-config.json b/build-tests/api-extractor-scenarios/config/build-config.json index ee4bc6e2718..80ec5180ec8 100644 --- a/build-tests/api-extractor-scenarios/config/build-config.json +++ b/build-tests/api-extractor-scenarios/config/build-config.json @@ -31,6 +31,7 @@ "preapproved", "typeOf", "typeOf2", + "typeOf3", "typeParameters" ] } diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/api-extractor-scenarios.api.json new file mode 100644 index 00000000000..19f566fe69e --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/api-extractor-scenarios.api.json @@ -0,0 +1,153 @@ +{ + "metadata": { + "toolPackage": "@microsoft/api-extractor", + "toolVersion": "[test mode]", + "schemaVersion": 1003, + "oldestForwardsCompatibleVersion": 1001 + }, + "kind": "Package", + "canonicalReference": "api-extractor-scenarios!", + "docComment": "", + "name": "api-extractor-scenarios", + "members": [ + { + "kind": "EntryPoint", + "canonicalReference": "api-extractor-scenarios!", + "name": "", + "members": [ + { + "kind": "Function", + "canonicalReference": "api-extractor-scenarios!f1:function(1)", + "docComment": "/**\n * A function that references its own parameter type.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function f1(x: " + }, + { + "kind": "Content", + "text": "number" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "typeof " + }, + { + "kind": "Reference", + "text": "x", + "canonicalReference": "api-extractor-scenarios!~x:var" + }, + { + "kind": "Content", + "text": ";" + } + ], + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 5 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "x", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + } + ], + "name": "f1" + }, + { + "kind": "Function", + "canonicalReference": "api-extractor-scenarios!f2:function(1)", + "docComment": "/**\n * A function that indirectly references its own parameter type.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function f2(x: " + }, + { + "kind": "Content", + "text": "number" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "keyof typeof " + }, + { + "kind": "Reference", + "text": "x", + "canonicalReference": "api-extractor-scenarios!~x:var" + }, + { + "kind": "Content", + "text": ";" + } + ], + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 5 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "x", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + } + ], + "name": "f2" + }, + { + "kind": "Function", + "canonicalReference": "api-extractor-scenarios!f3:function(1)", + "docComment": "/**\n * A function that references its own type.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare function f3(): " + }, + { + "kind": "Content", + "text": "typeof " + }, + { + "kind": "Reference", + "text": "f3", + "canonicalReference": "api-extractor-scenarios!f3:function" + }, + { + "kind": "Content", + "text": " | undefined" + }, + { + "kind": "Content", + "text": ";" + } + ], + "returnTypeTokenRange": { + "startIndex": 1, + "endIndex": 4 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [], + "name": "f3" + } + ] + } + ] +} diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/api-extractor-scenarios.api.md b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/api-extractor-scenarios.api.md new file mode 100644 index 00000000000..eb5a7b06549 --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/api-extractor-scenarios.api.md @@ -0,0 +1,19 @@ +## API Report File for "api-extractor-scenarios" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// @public +export function f1(x: number): typeof x; + +// @public +export function f2(x: number): keyof typeof x; + +// @public +export function f3(): typeof f3 | undefined; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/rollup.d.ts b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/rollup.d.ts new file mode 100644 index 00000000000..b6babbe2c89 --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/typeOf3/rollup.d.ts @@ -0,0 +1,17 @@ + +/** + * A function that references its own parameter type. + */ +export declare function f1(x: number): typeof x; + +/** + * A function that indirectly references its own parameter type. + */ +export declare function f2(x: number): keyof typeof x; + +/** + * A function that references its own type. + */ +export declare function f3(): typeof f3 | undefined; + +export { } diff --git a/build-tests/api-extractor-scenarios/src/typeOf3/index.ts b/build-tests/api-extractor-scenarios/src/typeOf3/index.ts new file mode 100644 index 00000000000..5819fffecae --- /dev/null +++ b/build-tests/api-extractor-scenarios/src/typeOf3/index.ts @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +/** + * A function that references its own parameter type. + * @public + */ +export function f1(x: number): typeof x { + return x; +} + +/** + * A function that indirectly references its own parameter type. + * @public + */ +export function f2(x: number): keyof typeof x { + return 'valueOf'; +} + +/** + * A function that references its own type. + * @public + */ +export function f3(): typeof f3 | undefined { + return undefined; +} diff --git a/common/changes/@microsoft/api-extractor/octgonz-ae-typeof-fix_2020-09-29-01-58.json b/common/changes/@microsoft/api-extractor/octgonz-ae-typeof-fix_2020-09-29-01-58.json new file mode 100644 index 00000000000..76b1ccb8b87 --- /dev/null +++ b/common/changes/@microsoft/api-extractor/octgonz-ae-typeof-fix_2020-09-29-01-58.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@microsoft/api-extractor", + "comment": "Fix an InternalError reported when a declaration referred to itself using \"tyepof\"", + "type": "patch" + } + ], + "packageName": "@microsoft/api-extractor", + "email": "4673363+octogonz@users.noreply.github.com" +} \ No newline at end of file