Skip to content

Commit

Permalink
Merge pull request #228 from arethetypeswrong/bug/222
Browse files Browse the repository at this point in the history
Filter `prototype` from expected named exports
  • Loading branch information
andrewbranch authored Dec 6, 2024
2 parents 953e617 + 5f96cdc commit c09df85
Show file tree
Hide file tree
Showing 4 changed files with 405 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/breezy-avocados-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@arethetypeswrong/core": patch
---

Filter `prototype` from expected named exports
44 changes: 27 additions & 17 deletions packages/core/src/internal/checks/namedExports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,22 @@ export default defineCheck({
}

const typeChecker = host.createAuxiliaryProgram([typesFileName]).getTypeChecker();
const expectedNames = typeChecker
.getExportsAndPropertiesOfModule(typesSourceFile.symbol)
// @ts-expect-error `getSymbolFlags` extra arguments are not declared on TypeChecker
.filter((symbol) => typeChecker.getSymbolFlags(symbol, /*excludeTypeOnlyMeanings*/ true) & ts.SymbolFlags.Value)
.map((symbol) => symbol.name);
const expectedNames = Array.from(
new Set(
typeChecker
.getExportsAndPropertiesOfModule(typesSourceFile.symbol)
.filter((symbol) => {
return (
// TS treats `prototype` and other static class members as exports. There's possibly
// a fix to be done in TS itself, since these show up as auto-imports.
symbol.name !== "prototype" &&
// @ts-expect-error `getSymbolFlags` extra arguments are not declared on TypeChecker
typeChecker.getSymbolFlags(symbol, /*excludeTypeOnlyMeanings*/ true) & ts.SymbolFlags.Value
);
})
.map((symbol) => symbol.name),
),
);

// Get actual exported names as seen by nodejs
let exports: readonly string[] | undefined;
Expand All @@ -51,20 +62,19 @@ export default defineCheck({
} catch {
// If this fails then the result is indeterminate. This could happen in many cases, but
// a common one would be for packages which re-export from another another package.
return;
}

if (exports) {
const missing = expectedNames.filter((name) => !exports.includes(name));
if (missing.length > 0) {
const lengthWithoutDefault = (names: readonly string[]) => names.length - (names.includes("default") ? 1 : 0);
return {
kind: "NamedExports",
implementationFileName,
typesFileName,
isMissingAllNamed: lengthWithoutDefault(missing) === lengthWithoutDefault(expectedNames),
missing,
};
}
const missing = expectedNames.filter((name) => !exports.includes(name));
if (missing.length > 0) {
const lengthWithoutDefault = (names: readonly string[]) => names.length - (names.includes("default") ? 1 : 0);
return {
kind: "NamedExports",
implementationFileName,
typesFileName,
isMissingAllNamed: lengthWithoutDefault(missing) === lengthWithoutDefault(expectedNames),
missing,
};
}
},
});
Binary file not shown.
Loading

0 comments on commit c09df85

Please sign in to comment.