Skip to content

Commit 9405f21

Browse files
authored
Don’t enforce export/declare overload modifier consistency across module augmentations (#59416)
1 parent 9757109 commit 9405f21

File tree

4 files changed

+55
-22
lines changed

4 files changed

+55
-22
lines changed

src/compiler/checker.ts

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41906,7 +41906,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4190641906
}
4190741907

4190841908
function checkFunctionOrConstructorSymbolWorker(symbol: Symbol): void {
41909-
function getCanonicalOverload(overloads: Declaration[], implementation: FunctionLikeDeclaration | undefined): Declaration {
41909+
function getCanonicalOverload(overloads: readonly Declaration[], implementation: FunctionLikeDeclaration | undefined): Declaration {
4191041910
// Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
4191141911
// Error on all deviations from this canonical set of flags
4191241912
// The caveat is that if some overloads are defined in lib.d.ts, we don't want to
@@ -41922,19 +41922,35 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4192241922
const someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
4192341923
if (someButNotAllOverloadFlags !== 0) {
4192441924
const canonicalFlags = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
41925-
forEach(overloads, o => {
41926-
const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags;
41927-
if (deviation & ModifierFlags.Export) {
41928-
error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
41929-
}
41930-
else if (deviation & ModifierFlags.Ambient) {
41931-
error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
41932-
}
41933-
else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) {
41934-
error(getNameOfDeclaration(o) || o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
41935-
}
41936-
else if (deviation & ModifierFlags.Abstract) {
41937-
error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
41925+
group(overloads, o => getSourceFileOfNode(o).fileName).forEach(overloadsInFile => {
41926+
const canonicalFlagsForFile = getEffectiveDeclarationFlags(getCanonicalOverload(overloadsInFile, implementation), flagsToCheck);
41927+
for (const o of overloadsInFile) {
41928+
const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags;
41929+
const deviationInFile = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlagsForFile;
41930+
if (deviationInFile & ModifierFlags.Export) {
41931+
// Overloads in different files need not all have export modifiers. This is ok:
41932+
// // lib.d.ts
41933+
// declare function foo(s: number): string;
41934+
// declare function foo(s: string): number;
41935+
// export { foo };
41936+
//
41937+
// // app.ts
41938+
// declare module "lib" {
41939+
// export function foo(s: boolean): boolean;
41940+
// }
41941+
error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
41942+
}
41943+
else if (deviationInFile & ModifierFlags.Ambient) {
41944+
// Though rare, a module augmentation (necessarily ambient) is allowed to add overloads
41945+
// to a non-ambient function in an implementation file.
41946+
error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
41947+
}
41948+
else if (deviation & (ModifierFlags.Private | ModifierFlags.Protected)) {
41949+
error(getNameOfDeclaration(o) || o, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
41950+
}
41951+
else if (deviation & ModifierFlags.Abstract) {
41952+
error(getNameOfDeclaration(o), Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
41953+
}
4193841954
}
4193941955
});
4194041956
}

tests/baselines/reference/missingFunctionImplementation2.errors.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
missingFunctionImplementation2_a.ts(3,19): error TS2384: Overload signatures must all be ambient or non-ambient.
21
missingFunctionImplementation2_b.ts(1,17): error TS2391: Function implementation is missing or not immediately following the declaration.
32

43

5-
==== missingFunctionImplementation2_a.ts (1 errors) ====
4+
==== missingFunctionImplementation2_a.ts (0 errors) ====
65
export {};
76
declare module "./missingFunctionImplementation2_b" {
87
export function f(a, b): void;
9-
~
10-
!!! error TS2384: Overload signatures must all be ambient or non-ambient.
118
}
129

1310
==== missingFunctionImplementation2_b.ts (1 errors) ====
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
parserStrictMode8.ts(2,10): error TS1100: Invalid use of 'eval' in strict mode.
2-
parserStrictMode8.ts(2,10): error TS2384: Overload signatures must all be ambient or non-ambient.
32

43

5-
==== parserStrictMode8.ts (2 errors) ====
4+
==== parserStrictMode8.ts (1 errors) ====
65
"use strict";
76
function eval() {
87
~~~~
98
!!! error TS1100: Invalid use of 'eval' in strict mode.
10-
~~~~
11-
!!! error TS2384: Overload signatures must all be ambient or non-ambient.
129
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// @strict: true
2+
// @module: preserve
3+
// @noEmit: true
4+
// @noTypesAndSymbols: true
5+
6+
// @Filename: node_modules/library/index.d.ts
7+
declare function get(): string;
8+
9+
export { get };
10+
11+
// @Filename: node_modules/non-ambient/index.ts
12+
export function real(arg?: string): any {}
13+
14+
// @Filename: augmentations.d.ts
15+
export {};
16+
17+
declare module "library" {
18+
export function get(): string | null;
19+
}
20+
21+
declare module "non-ambient" {
22+
export function real(arg: string): string;
23+
}

0 commit comments

Comments
 (0)