@@ -38,11 +38,22 @@ export default defineCheck({
38
38
}
39
39
40
40
const typeChecker = host . createAuxiliaryProgram ( [ typesFileName ] ) . getTypeChecker ( ) ;
41
- const expectedNames = typeChecker
42
- . getExportsAndPropertiesOfModule ( typesSourceFile . symbol )
43
- // @ts -expect-error `getSymbolFlags` extra arguments are not declared on TypeChecker
44
- . filter ( ( symbol ) => typeChecker . getSymbolFlags ( symbol , /*excludeTypeOnlyMeanings*/ true ) & ts . SymbolFlags . Value )
45
- . map ( ( symbol ) => symbol . name ) ;
41
+ const expectedNames = Array . from (
42
+ new Set (
43
+ typeChecker
44
+ . getExportsAndPropertiesOfModule ( typesSourceFile . symbol )
45
+ . filter ( ( symbol ) => {
46
+ return (
47
+ // TS treats `prototype` and other static class members as exports. There's possibly
48
+ // a fix to be done in TS itself, since these show up as auto-imports.
49
+ symbol . name !== "prototype" &&
50
+ // @ts -expect-error `getSymbolFlags` extra arguments are not declared on TypeChecker
51
+ typeChecker . getSymbolFlags ( symbol , /*excludeTypeOnlyMeanings*/ true ) & ts . SymbolFlags . Value
52
+ ) ;
53
+ } )
54
+ . map ( ( symbol ) => symbol . name ) ,
55
+ ) ,
56
+ ) ;
46
57
47
58
// Get actual exported names as seen by nodejs
48
59
let exports : readonly string [ ] | undefined ;
@@ -51,20 +62,19 @@ export default defineCheck({
51
62
} catch {
52
63
// If this fails then the result is indeterminate. This could happen in many cases, but
53
64
// a common one would be for packages which re-export from another another package.
65
+ return ;
54
66
}
55
67
56
- if ( exports ) {
57
- const missing = expectedNames . filter ( ( name ) => ! exports . includes ( name ) ) ;
58
- if ( missing . length > 0 ) {
59
- const lengthWithoutDefault = ( names : readonly string [ ] ) => names . length - ( names . includes ( "default" ) ? 1 : 0 ) ;
60
- return {
61
- kind : "NamedExports" ,
62
- implementationFileName,
63
- typesFileName,
64
- isMissingAllNamed : lengthWithoutDefault ( missing ) === lengthWithoutDefault ( expectedNames ) ,
65
- missing,
66
- } ;
67
- }
68
+ const missing = expectedNames . filter ( ( name ) => ! exports . includes ( name ) ) ;
69
+ if ( missing . length > 0 ) {
70
+ const lengthWithoutDefault = ( names : readonly string [ ] ) => names . length - ( names . includes ( "default" ) ? 1 : 0 ) ;
71
+ return {
72
+ kind : "NamedExports" ,
73
+ implementationFileName,
74
+ typesFileName,
75
+ isMissingAllNamed : lengthWithoutDefault ( missing ) === lengthWithoutDefault ( expectedNames ) ,
76
+ missing,
77
+ } ;
68
78
}
69
79
} ,
70
80
} ) ;
0 commit comments