-
Notifications
You must be signed in to change notification settings - Fork 622
[api-extractor] Extending anonymous classes errors that _base
class inserted by compiler is not exported.
#4429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Here's an expanded example: example.ts /** Docs for Foo */
export class Foo extends class {
/** Docs for X */
x: number = 1;
} {
/** Docs for Y */
y: number = 2;
} example.js /** Docs for Foo */
export class Foo extends class {
constructor() {
/** Docs for X */
this.x = 1;
}
} {
constructor() {
super(...arguments);
/** Docs for Y */
this.y = 2;
}
} example.d.ts declare const Foo_base: {
new (): {
/** Docs for X */
x: number;
};
};
/** Docs for Foo */
export declare class Foo extends Foo_base {
/** Docs for Y */
y: number;
}
export {}; We can see that:
I think it would be a reasonable heuristic to say that:
That is very unlikely to conflict with any realistic API designs when using API Extractor. |
🤔 But then this code... export interface Foo_base { }
export class Foo extends class { } { } ...produces a export interface Foo_base {
}
declare const Foo_base_1: {
new (): {};
};
export declare class Foo extends Foo_base_1 {
}
export {}; |
Here's a different approach: Maybe we could introduce a new TSDoc tag ( Example: /** Docs for Foo */
export class Foo extends class {
/** Docs for X */
x: number = 1;
} {
/** Docs for Y */
y: number = 2;
}
/**
* This declaration is part of the {@link Foo} type.
*
* @public
* {@applyToEmitted Foo_base}
*/ This is not as elegant as guessing that Whereas, on the other hand, if we were taking the approach of /** {@partOf Foo} {@applyToEmitted Foo_base} */ ...but that |
I field microsoft/TypeScript#59550 in the TypeScript repo which would avoid this issue if implemented. |
Summary
Produces:
Putting an API-Extractor release tag on "Foo" results in an "ae-forgotten-export" that there is no release tag on "Foo_base".
However this is no clean way to put the release tag on "Foo_base" other than refactoring the code to explicitly export the base class.
Playground link
Ideally extra non-exported types with mangled names which TSC adds as an implementation detail of d.ts files would not impact API-Extractor. I think suppressing the warning/error in this case would be the optimal outcome.
Unfortunately I don't think there is a truly robust way to detect this case just looking at the d.ts file, since developers can manually export types named SomeClass_base. (Note that in this case TSC may generate a name of the format SomeClass_base_1 to avoid the collision), but just suppressing the warning/error for all non-exported classes of the format SomeClass_base_1 or SomeClass_base would be enough for our use cases.
If adding a special case for this pattern is not a good solution, detecting these cases (as effectively as possible) as a heuristic to add a better error message for this case. For example:
The symbol "SomeClass_base" needs to be exported by the entry point index.d.ts. This type may have been implicitly generated by the TypeScript compiler for the base type of a class which extends an anonymous class expression. In this case this error can be resolved by explicitly exporting the result of that expression, then extending that exported constant.
Another option would be to include a config setting to opt out of this case being an error.
Repro steps
Expected result: No errors, or a more specific error.
Actual result:
Error: src/class-tree/testRecursiveDomain.ts:32:1 - (ae-forgotten-export) The symbol "RecursiveObject_base" needs to be exported by the entry point index.d.ts
Details
This came up with the schema system we are creating for Fluid-Framework's trees. All users of our schema system which export schema and use API-Extractor will hit this.
A real world example of this is in https://github.com/microsoft/FluidFramework/pull/18350/files/5a2309887741c6e4a7976b824f062960ec32f02a..7dcf01f1717e5f021e2c2c9f9238fa65038b3e47#diff-7006e9416c4e849ea87906ed645eab13666c035fe928e478446c9bd1cf0f4ea8
This pattern was partially adopted to work around microsoft/TypeScript#55832 : Using classes like this lets the compiler refer to them easier and avoid generating
any
in some recursive cases. There are also other reasons we like this pattern (it allows apps to add methods to schema, works with instanceof, gets better intelisense).I suspect other mixing type patterns might hit this as well.
Standard questions
Please answer these questions to help us investigate your issue more quickly:
@microsoft/api-extractor
version?node -v
)?The text was updated successfully, but these errors were encountered: