Skip to content

tspd: gen-extern-signatures is broken for subpath exports #8913

@witemple-msft

Description

@witemple-msft

TSPD attempts to generate signatures for subpath exports defined in package.json, but the workflow is mostly broken.

The way subpaths work today is that TSPD accumulates any entry in exports that contains a typespec specifier. It then compiles all subpaths together in a single Program using options.additionalImports when compiling the Program, where the first export is always treated as the main entrypoint.

Unfortunately, it has no way to know where a particular decorator was defined, which makes it impossible to implement correct libraries with extern signatures for subpaths, because:

  • TSPD always treats $decorators as if it were exported from the root of the package, even for decorators defined in subpaths, which could be imported from anywhere defined in the TSP file itself (but it seems reasonable to assume it should be exported by the JS path that maps to the same subpath, because we are making the same general assumption for the root path).
  • If the decorator implementation is provided in the root $decorators exported by the package index for the root import path, the library linter will complain that there is no corresponding extern dec declaration in TypeSpec for these decorators, and the decorators will be available to the compiler even if the subpath was not imported, so this is not correct.
  • If the decorator implementation is provided in $decorators exported by the subpath index, which is correct from a library structural standpoint, TSPD cannot generate a <Namespace>.ts-test.ts that gets the correct $decorators from that path, because it does not know which subpath maps to a given decorator in the Program's type graph. So you get TS typechecking errors on that test.ts file because it expects the wrong structure of the root $decorators.

This is a difficult problem to solve because:

  • Where a decorator is defined is lexical in nature, so we will likely have to work with AST Nodes rather than Type Graph nodes.
  • The mapping from subpaths to files loaded by a subpath does not have any nice function properties, as a file can be loaded by multiple subpaths and the mapping is not invertible. It isn't easy to figure out which subpaths could load a source file other than by compiling each subpath individually, but then we also have the problem that many subpaths will load the same source files (import ../lib.ts to load the rest of the library when a special subpath is used is common).

For now, we're going to disable generating signatures for subpaths since it makes writing subpaths that expose decorators structurally impossible without requiring downstream libraries to fixup the generated signatures using bespoke scripts.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions