microsoft / rushstack

Monorepo for tools developed by the Rush Stack community
https://rushstack.io/
Other
5.9k stars 595 forks source link

[api-extractor] Interface with field aliasing type parameter throws "Child declaration not found for the specified node" #2834

Open spenceryue opened 3 years ago

spenceryue commented 3 years ago

Summary

I was trying to flatten the d.ts files output by Angular 10 (as recommended here), because the stray d.ts files seemed to cause issues when passed into ngcc (Error: Compiled class declaration is not inside an IIFE).

Repro steps

Minimal entry file to reproduce error:

// builds/dist/common/public_api.d.ts
export interface A<T> {
    T: any;
};

Config:

// src/common/api-extractor.json
{
    "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
    "apiReport": {
        "enabled": false,
        "reportFileName": "<unscopedPackageName>.api.md",
        "reportFolder": "../../api/",
        "reportTempFolder": "../../api/next/"
    },
    "compiler": {
        "tsconfigFilePath": "../prod.tsconfig.json"
    },
    "docModel": {
        "apiJsonFilePath": "../../builds/api/<unscopedPackageName>.api.json",
        "enabled": false
    },
    "dtsRollup": {
        "enabled": true,
        "untrimmedFilePath": "../../builds/api/<unscopedPackageName>.d.ts"
    },
    "mainEntryPointFilePath": "../../builds/dist/common/public_api.d.ts",
    "newlineKind": "lf",
    "tsdocMetadata": {
        "enabled": false,
        "tsdocMetadataFilePath": "../../builds/api/<unscopedPackageName>.tsdoc-metadata.json"
    }
}

Command:

api-extractor run --config src/common/api-extractor.json --typescript-compiler-folder node_modules/typescript

Details

I narrowed down the "specified node" (referenced in the error message) by logging node.getText() and node.getSourceFile().fileName here (just before the error is thrown).

When I logged the following at line 681 (the only place that this._astDeclarationsByDeclaration.set is ever called), I saw that indeed the "specified node" was never printed.

console.log({ declaration: declaration.getText(), localName: astDeclaration.astSymbol.localName });

Here's is the output with --diagnostics. (Note: The second line of text Analysis will use the bundled TypeScript version 4.3.5 seems wrong. I'm using TS 4.0.8.)


api-extractor 7.18.4  - https://api-extractor.com/

Analysis will use the bundled TypeScript version 4.3.5

============================================================
DIAGNOSTIC: Final prepared ExtractorConfig
============================================================
{
  "projectFolder": "/Users/my-username/Desktop/my-repo/src",
  "packageJson": {
    "bin": null,
    "dependencies": {
      "ag-grid-angular": "25.1.0",
      "ag-grid-community": "25.1.0",
      "ag-grid-enterprise": "25.1.0",
      "common-tags": "1.8.0",
      "highcharts": "9.0.1",
      "timezone-support": "2.0.2",
      "tslib": "^2.0.0"
    },
    "description": null,
    "devDependencies": {
      "@microsoft/api-extractor": "7.18.4",
      "@types/common-tags": "1.8.0",
      "@types/resize-observer-browser": "0.1.5",
      "@types/segment-analytics": "^0.0.32"
    },
    "homepage": null,
    "license": null,
    "main": null,
    "name": "@my-company/my-library",
    "optionalDependencies": null,
    "peerDependencies": {
      "@angular/animations": "10.2.5",
      "@angular/cdk": "10.2.7",
      "@angular/common": "10.2.5",
      "@angular/core": "10.2.5",
      "@angular/forms": "10.2.5",
      "@angular/material": "^10.2.7",
      "@angular/platform-browser": "10.2.5",
      "@my-company/ui-assets": "^7.0.3",
      "lodash": "^4.17.20",
      "rxjs": "^6.6.0"
    },
    "private": null,
    "scripts": null,
    "typings": null,
    "tsdocMetadata": null,
    "version": null
  },
  "packageFolder": "/Users/my-username/Desktop/my-repo/src",
  "mainEntryPointFilePath": "/Users/my-username/Desktop/my-repo/builds/dist/common/public_api.d.ts",
  "bundledPackages": [],
  "tsconfigFilePath": "/Users/my-username/Desktop/my-repo/src/prod.tsconfig.json",
  "overrideTsconfig": null,
  "skipLibCheck": false,
  "apiReportEnabled": false,
  "reportFilePath": "/Users/my-username/Desktop/my-repo/api/my-library.api.md",
  "reportTempFilePath": "/Users/my-username/Desktop/my-repo/api/next/my-library.api.md",
  "docModelEnabled": false,
  "apiJsonFilePath": "/Users/my-username/Desktop/my-repo/builds/api/my-library.api.json",
  "rollupEnabled": true,
  "untrimmedFilePath": "/Users/my-username/Desktop/my-repo/builds/api/my-library.d.ts",
  "betaTrimmedFilePath": "",
  "publicTrimmedFilePath": "",
  "omitTrimmingComments": false,
  "tsdocMetadataEnabled": false,
  "tsdocMetadataFilePath": "",
  "newlineKind": "\n",
  "messages": {
    "compilerMessageReporting": {
      "default": {
        "logLevel": "warning"
      }
    },
    "extractorMessageReporting": {
      "default": {
        "logLevel": "warning"
      },
      "ae-forgotten-export": {
        "logLevel": "warning",
        "addToApiReportFile": true
      },
      "ae-incompatible-release-tags": {
        "logLevel": "warning",
        "addToApiReportFile": true
      },
      "ae-internal-missing-underscore": {
        "logLevel": "warning",
        "addToApiReportFile": true
      },
      "ae-internal-mixed-release-tag": {
        "logLevel": "warning",
        "addToApiReportFile": true
      },
      "ae-unresolved-inheritdoc-reference": {
        "logLevel": "warning",
        "addToApiReportFile": true
      },
      "ae-unresolved-inheritdoc-base": {
        "logLevel": "warning",
        "addToApiReportFile": true
      }
    },
    "tsdocMessageReporting": {
      "default": {
        "logLevel": "warning"
      }
    }
  },
  "testMode": false,
  "tsdocConfigFile": {
    "filePath": "/Users/my-username/Desktop/my-repo/src/node_modules/@microsoft/api-extractor/extends/tsdoc-base.json",
    "log": []
  }
}
============================================================

============================================================
DIAGNOSTIC: Compiler options
============================================================
{
  "allowSyntheticDefaultImports": true,
  "alwaysStrict": true,
  "declaration": true,
  "disableSizeLimit": true,
  "downlevelIteration": true,
  "emitDecoratorMetadata": false,
  "esModuleInterop": true,
  "experimentalDecorators": true,
  "importHelpers": true,
  "inlineSources": true,
  "lib": [
    "lib.dom.d.ts",
    "lib.es2015.d.ts"
  ],
  "module": 6,
  "moduleResolution": 2,
  "noErrorTruncation": true,
  "noImplicitAny": true,
  "noImplicitReturns": true,
  "noImplicitThis": true,
  "noUnusedParameters": true,
  "outDir": "/Users/my-username/Desktop/my-repo/builds/out-tsc",
  "resolveJsonModule": true,
  "sourceMap": true,
  "strictBindCallApply": true,
  "strictFunctionTypes": true,
  "strictNullChecks": true,
  "stripInternal": false,
  "target": 2,
  "baseUrl": "/Users/my-username/Desktop/my-repo/.tsconfig",
  "paths": {
    "*": [
      "../src/node_modules/*"
    ],
    "//": [
      "Do not add your own `paths` property in the child tsconfig as it will override the path mappings",
      "defined here."
    ],
    "@my-company/my-library": [
      "../builds/dist"
    ],
    "@my-company/my-library/assets/*": [
      "../builds/dist/assets/*"
    ],
    "@my-company/my-library/common": [
      "../builds/dist/common"
    ]
  },
  "pathsBasePath": "/Users/my-username/Desktop/my-repo/.tsconfig",
  "declarationMap": true,
  "configFilePath": null
}
============================================================

============================================================
DIAGNOSTIC: TSDoc configuration
============================================================
{
  "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
  "noStandardTags": true,
  "tagDefinitions": [
    {
      "tagName": "@alpha",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@beta",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@defaultValue",
      "syntaxKind": "block"
    },
    {
      "tagName": "@decorator",
      "syntaxKind": "block",
      "allowMultiple": true
    },
    {
      "tagName": "@deprecated",
      "syntaxKind": "block"
    },
    {
      "tagName": "@eventProperty",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@example",
      "syntaxKind": "block",
      "allowMultiple": true
    },
    {
      "tagName": "@experimental",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@inheritDoc",
      "syntaxKind": "inline"
    },
    {
      "tagName": "@internal",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@label",
      "syntaxKind": "inline"
    },
    {
      "tagName": "@link",
      "syntaxKind": "inline",
      "allowMultiple": true
    },
    {
      "tagName": "@override",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@packageDocumentation",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@param",
      "syntaxKind": "block",
      "allowMultiple": true
    },
    {
      "tagName": "@privateRemarks",
      "syntaxKind": "block"
    },
    {
      "tagName": "@public",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@readonly",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@remarks",
      "syntaxKind": "block"
    },
    {
      "tagName": "@returns",
      "syntaxKind": "block"
    },
    {
      "tagName": "@sealed",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@see",
      "syntaxKind": "block"
    },
    {
      "tagName": "@throws",
      "syntaxKind": "block",
      "allowMultiple": true
    },
    {
      "tagName": "@typeParam",
      "syntaxKind": "block",
      "allowMultiple": true
    },
    {
      "tagName": "@virtual",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@betaDocumentation",
      "syntaxKind": "modifier"
    },
    {
      "tagName": "@internalRemarks",
      "syntaxKind": "block"
    },
    {
      "tagName": "@preapproved",
      "syntaxKind": "modifier"
    }
  ],
  "supportForTags": {
    "@alpha": true,
    "@beta": true,
    "@defaultValue": true,
    "@decorator": true,
    "@deprecated": true,
    "@eventProperty": true,
    "@example": true,
    "@experimental": true,
    "@inheritDoc": true,
    "@internal": true,
    "@label": true,
    "@link": true,
    "@override": true,
    "@packageDocumentation": true,
    "@param": true,
    "@privateRemarks": true,
    "@public": true,
    "@readonly": true,
    "@remarks": true,
    "@returns": true,
    "@sealed": true,
    "@see": true,
    "@throws": true,
    "@typeParam": true,
    "@virtual": true,
    "@betaDocumentation": true,
    "@internalRemarks": true,
    "@preapproved": true
  }
}
============================================================

============================================================
DIAGNOSTIC: Root filenames
============================================================
/Users/my-username/Desktop/my-repo/builds/dist/common/public_api.d.ts
============================================================

============================================================
DIAGNOSTIC: Files analyzed by compiler
============================================================
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es5.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2016.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2017.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2018.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.dom.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.core.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.collection.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.generator.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.iterable.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.promise.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.proxy.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.reflect.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.symbol.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2016.array.include.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2017.object.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2017.string.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2017.intl.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2018.intl.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2018.promise.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2018.regexp.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.es2020.bigint.d.ts
/Users/my-username/Desktop/my-repo/node_modules/typescript/lib/lib.esnext.intl.d.ts
/Users/my-username/Desktop/my-repo/builds/dist/common/public_api.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/component-emitter/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/cookie/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/cors/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/estree/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/assert/strict.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/globals.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/async_hooks.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/buffer.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/child_process.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/cluster.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/console.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/constants.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/crypto.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/dgram.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/diagnostic_channel.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/dns.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/dns/promises.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/domain.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/events.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/fs.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/fs/promises.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/http.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/http2.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/https.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/inspector.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/module.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/net.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/os.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/path.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/perf_hooks.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/process.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/punycode.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/querystring.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/readline.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/repl.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/stream.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/stream/promises.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/string_decoder.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/timers.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/timers/promises.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/tls.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/trace_events.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/tty.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/url.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/util.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/util/types.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/v8.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/vm.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/worker_threads.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/zlib.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/globals.global.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/wasi.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/ts3.6/base.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/assert.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/base.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/node_modules/@types/node/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/minimatch/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/glob/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/json-schema/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/common.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/array.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/collection.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/date.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/function.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/lang.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/math.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/number.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/object.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/seq.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/string.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/common/util.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/lodash/ts3.1/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/unist/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/mdast/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/minimist/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/normalize-package-data/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/parse-json/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/q/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/resolve/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/source-list-map/index.d.ts
/Users/my-username/Desktop/my-repo/src/node_modules/source-map/source-map.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/webpack-sources/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/yargs-parser/index.d.ts
/Users/my-username/Desktop/my-repo/node_modules/@types/yargs/index.d.ts
============================================================

Writing package typings: /Users/my-username/Desktop/my-repo/builds/api/my-library.d.ts

ERROR: Child declaration not found for the specified node

Standard questions

Please answer these questions to help us investigate your issue more quickly:

Question Answer
@microsoft/api-extractor version? 7.18.4
Operating system? Mac
API Extractor scenario? rollups (.d.ts)
Would you consider contributing a PR? No
TypeScript compiler version? 4.0.8
Node.js version (node -v)? 14.17.0
octogonz commented 3 years ago

I narrowed down the "specified node" (referenced in the error message) by logging node.getText() and node.getSourceFile().fileName here (just before the error is thrown).

This should probably be reported as InternalError and the message should include more context using SourceFileLocationFormatter.formatDeclaration().

The problem is caused by newfangled type algebra T: any that puts a ts.SyntaxKind.PropertySignature in a place where a property name normally goes.

It is basically an assertion failure, because getChildAstDeclarationByNode() expects that node to have been traversed previously, but it wasn't, because T is hiding in a place were the visitor does not look for types:

https://github.com/microsoft/rushstack/blob/a6ce57ac7b08d95f145cfa2c105a2c21053c16a5/apps/api-extractor/src/generators/ApiReportGenerator.ts#L394-L402

Without investigating deeper, my guess is that the type algebra has evolved to a level of complexity where AstDeclaration.isSupportedSyntaxKind() is no longer a sufficient test.

spenceryue commented 3 years ago

The problem is caused by newfangled type algebra T: any that puts a ts.SyntaxKind.PropertySignature in a place where a property name normally goes.

It seems from this thread that .PropertySignature is a pretty old concept (6 years).

Just to clarify, in the reproduction, the intent is not to somehow use the T parameter as a computed property name or index signature. The intent is just to have a field literally named "T". A more realistic usage:

interface SomeLongComputation<T> {
    // Refine the "raw" `T`.
    T: Extract<T, Foo>;

    // No type error about "`T` doesn't extend `Foo`".
    result: DoSomethingWith<this["T"]>;
}

// Notice the `extends Foo`.
type DoSomethingWith<T extends Foo> = T;

// Usage:
SomeLongComputation<T>["result"]

Analogous runtime code:

type Foo = {};

const someLongComputation = (t: any) => ({
    t: isFoo(t) ? t : "never",
    get result() {
        return doSomethingWith(this.t);
    },
});

const isFoo = (t: any): t is Foo => true;

const doSomethingWith = (t: Foo | "never") => t;

// Usage:
someLongComputation(t).result