Skip to content

Commit 25ab551

Browse files
authored
Report implict any error when widening null/undefined in presence of … (#59661)
1 parent 825826f commit 25ab551

9 files changed

+363
-12
lines changed

src/compiler/checker.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25674,7 +25674,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2567425674
case SyntaxKind.ArrowFunction:
2567525675
if (noImplicitAny && !(declaration as NamedDeclaration).name) {
2567625676
if (wideningKind === WideningKind.GeneratorYield) {
25677-
error(declaration, Diagnostics.Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation, typeAsString);
25677+
error(declaration, Diagnostics.Generator_implicitly_has_yield_type_0_Consider_supplying_a_return_type_annotation, typeAsString);
2567825678
}
2567925679
else {
2568025680
error(declaration, Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
@@ -25696,12 +25696,40 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2569625696
errorOrSuggestion(noImplicitAny, declaration, diagnostic, declarationNameToString(getNameOfDeclaration(declaration)), typeAsString);
2569725697
}
2569825698

25699+
function shouldReportErrorsFromWideningWithContextualSignature(declaration: FunctionLikeDeclaration, wideningKind: WideningKind) {
25700+
const signature = getContextualSignatureForFunctionLikeDeclaration(declaration);
25701+
if (!signature) {
25702+
return true;
25703+
}
25704+
let returnType = getReturnTypeOfSignature(signature);
25705+
const flags = getFunctionFlags(declaration);
25706+
switch (wideningKind) {
25707+
case WideningKind.FunctionReturn:
25708+
if (flags & FunctionFlags.Generator) {
25709+
returnType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, !!(flags & FunctionFlags.Async)) ?? returnType;
25710+
}
25711+
else if (flags & FunctionFlags.Async) {
25712+
returnType = getAwaitedTypeNoAlias(returnType) ?? returnType;
25713+
}
25714+
return isGenericType(returnType);
25715+
case WideningKind.GeneratorYield:
25716+
const yieldType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, returnType, !!(flags & FunctionFlags.Async));
25717+
return !!yieldType && isGenericType(yieldType);
25718+
case WideningKind.GeneratorNext:
25719+
const nextType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, returnType, !!(flags & FunctionFlags.Async));
25720+
return !!nextType && isGenericType(nextType);
25721+
}
25722+
return false;
25723+
}
25724+
2569925725
function reportErrorsFromWidening(declaration: Declaration, type: Type, wideningKind?: WideningKind) {
2570025726
addLazyDiagnostic(() => {
25701-
if (noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration as FunctionLikeDeclaration))) {
25702-
// Report implicit any error within type if possible, otherwise report error on declaration
25703-
if (!reportWideningErrorsInType(type)) {
25704-
reportImplicitAny(declaration, type, wideningKind);
25727+
if (noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType) {
25728+
if (!wideningKind || isFunctionLikeDeclaration(declaration) && shouldReportErrorsFromWideningWithContextualSignature(declaration, wideningKind)) {
25729+
// Report implicit any error within type if possible, otherwise report error on declaration
25730+
if (!reportWideningErrorsInType(type)) {
25731+
reportImplicitAny(declaration, type, wideningKind);
25732+
}
2570525733
}
2570625734
}
2570725735
});

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6667,7 +6667,7 @@
66676667
"category": "Error",
66686668
"code": 7024
66696669
},
6670-
"Generator implicitly has yield type '{0}' because it does not yield any values. Consider supplying a return type annotation.": {
6670+
"Generator implicitly has yield type '{0}'. Consider supplying a return type annotation.": {
66716671
"category": "Error",
66726672
"code": 7025
66736673
},

tests/baselines/reference/generatorReturnTypeInferenceNonStrict.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ generatorReturnTypeInferenceNonStrict.ts(74,15): error TS7057: 'yield' expressio
44
generatorReturnTypeInferenceNonStrict.ts(79,11): error TS7055: 'g301', which lacks return-type annotation, implicitly has an 'any' yield type.
55
generatorReturnTypeInferenceNonStrict.ts(89,11): error TS7055: 'g303', which lacks return-type annotation, implicitly has an 'any' yield type.
66
generatorReturnTypeInferenceNonStrict.ts(126,11): error TS7055: 'g310', which lacks return-type annotation, implicitly has an 'any' yield type.
7-
generatorReturnTypeInferenceNonStrict.ts(131,10): error TS7025: Generator implicitly has yield type 'any' because it does not yield any values. Consider supplying a return type annotation.
7+
generatorReturnTypeInferenceNonStrict.ts(131,10): error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
88

99

1010
==== generatorReturnTypeInferenceNonStrict.ts (7 errors) ====
@@ -152,7 +152,7 @@ generatorReturnTypeInferenceNonStrict.ts(131,10): error TS7025: Generator implic
152152
function* g311() { // Generator<any (implicit), void, string>
153153
yield* (function*() {
154154
~~~~~~~~
155-
!!! error TS7025: Generator implicitly has yield type 'any' because it does not yield any values. Consider supplying a return type annotation.
155+
!!! error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
156156
const y: string = yield;
157157
})();
158158
}

tests/baselines/reference/generatorTypeCheck62.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ generatorTypeCheck62.ts(32,62): error TS2345: Argument of type '(state: State) =
1212
Type 'IteratorReturnResult<State>' is not assignable to type 'IteratorResult<any, void>'.
1313
Type 'IteratorReturnResult<State>' is not assignable to type 'IteratorReturnResult<void>'.
1414
Type 'State' is not assignable to type 'void'.
15+
generatorTypeCheck62.ts(32,62): error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
1516

1617

17-
==== generatorTypeCheck62.ts (2 errors) ====
18+
==== generatorTypeCheck62.ts (3 errors) ====
1819
export interface StrategicState {
1920
lastStrategyApplied?: string;
2021
}
@@ -63,6 +64,8 @@ generatorTypeCheck62.ts(32,62): error TS2345: Argument of type '(state: State) =
6364
!!! error TS2345: Type 'IteratorReturnResult<State>' is not assignable to type 'IteratorResult<any, void>'.
6465
!!! error TS2345: Type 'IteratorReturnResult<State>' is not assignable to type 'IteratorReturnResult<void>'.
6566
!!! error TS2345: Type 'State' is not assignable to type 'void'.
67+
~~~~~~~~
68+
!!! error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
6669
yield ;
6770
return state; // `return`/`TReturn` isn't supported by `strategy`, so this should error.
6871
});
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
implicitAnyGenericTypeInference.ts(10,4): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
2+
implicitAnyGenericTypeInference.ts(13,4): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
3+
implicitAnyGenericTypeInference.ts(16,4): error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
4+
implicitAnyGenericTypeInference.ts(19,4): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
5+
implicitAnyGenericTypeInference.ts(22,4): error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
6+
implicitAnyGenericTypeInference.ts(25,4): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
7+
implicitAnyGenericTypeInference.ts(28,25): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
8+
implicitAnyGenericTypeInference.ts(29,24): error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
9+
10+
11+
==== implicitAnyGenericTypeInference.ts (8 errors) ====
12+
interface Comparer<T> {
13+
compareTo<U>(x: T, y: U): U;
14+
}
15+
16+
var c: Comparer<any>;
17+
c = { compareTo: (x, y) => { return y; } };
18+
var r = c.compareTo(1, '');
19+
20+
declare function f1<T>(cb: () => T): void;
21+
f1(() => null);
22+
~~~~~~~~~~
23+
!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
24+
25+
declare function f2<T>(cb: () => PromiseLike<T>): void;
26+
f2(async () => null);
27+
~~~~~~~~~~~~~~~~
28+
!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
29+
30+
declare function f3<T>(cb: () => Generator<T>): void;
31+
f3(function* () { yield null; });
32+
~~~~~~~~
33+
!!! error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
34+
35+
declare function f4<T>(cb: () => Generator<unknown, T>): void;
36+
f4(function* () { return null; });
37+
~~~~~~~~
38+
!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
39+
40+
declare function f5<T>(cb: () => AsyncGenerator<T>): void;
41+
f5(async function* () { yield null; });
42+
~~~~~
43+
!!! error TS7025: Generator implicitly has yield type 'any'. Consider supplying a return type annotation.
44+
45+
declare function f6<T>(cb: () => AsyncGenerator<unknown, T>): void;
46+
f6(async function* () { return null; });
47+
~~~~~
48+
!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
49+
50+
// https://github.com/microsoft/TypeScript/issues/44913
51+
Promise.resolve().catch(e => null);
52+
~~~~~~~~~
53+
!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
54+
Promise.resolve().then(v => null);
55+
~~~~~~~~~
56+
!!! error TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.

tests/baselines/reference/implicitAnyGenericTypeInference.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,40 @@ interface Comparer<T> {
77

88
var c: Comparer<any>;
99
c = { compareTo: (x, y) => { return y; } };
10-
var r = c.compareTo(1, '');
10+
var r = c.compareTo(1, '');
11+
12+
declare function f1<T>(cb: () => T): void;
13+
f1(() => null);
14+
15+
declare function f2<T>(cb: () => PromiseLike<T>): void;
16+
f2(async () => null);
17+
18+
declare function f3<T>(cb: () => Generator<T>): void;
19+
f3(function* () { yield null; });
20+
21+
declare function f4<T>(cb: () => Generator<unknown, T>): void;
22+
f4(function* () { return null; });
23+
24+
declare function f5<T>(cb: () => AsyncGenerator<T>): void;
25+
f5(async function* () { yield null; });
26+
27+
declare function f6<T>(cb: () => AsyncGenerator<unknown, T>): void;
28+
f6(async function* () { return null; });
29+
30+
// https://github.com/microsoft/TypeScript/issues/44913
31+
Promise.resolve().catch(e => null);
32+
Promise.resolve().then(v => null);
1133

1234
//// [implicitAnyGenericTypeInference.js]
1335
var c;
14-
c = { compareTo: function (x, y) { return y; } };
36+
c = { compareTo: (x, y) => { return y; } };
1537
var r = c.compareTo(1, '');
38+
f1(() => null);
39+
f2(async () => null);
40+
f3(function* () { yield null; });
41+
f4(function* () { return null; });
42+
f5(async function* () { yield null; });
43+
f6(async function* () { return null; });
44+
// https://github.com/microsoft/TypeScript/issues/44913
45+
Promise.resolve().catch(e => null);
46+
Promise.resolve().then(v => null);

tests/baselines/reference/implicitAnyGenericTypeInference.symbols

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,79 @@ var r = c.compareTo(1, '');
3232
>c : Symbol(c, Decl(implicitAnyGenericTypeInference.ts, 4, 3))
3333
>compareTo : Symbol(Comparer.compareTo, Decl(implicitAnyGenericTypeInference.ts, 0, 23))
3434

35+
declare function f1<T>(cb: () => T): void;
36+
>f1 : Symbol(f1, Decl(implicitAnyGenericTypeInference.ts, 6, 27))
37+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 8, 20))
38+
>cb : Symbol(cb, Decl(implicitAnyGenericTypeInference.ts, 8, 23))
39+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 8, 20))
40+
41+
f1(() => null);
42+
>f1 : Symbol(f1, Decl(implicitAnyGenericTypeInference.ts, 6, 27))
43+
44+
declare function f2<T>(cb: () => PromiseLike<T>): void;
45+
>f2 : Symbol(f2, Decl(implicitAnyGenericTypeInference.ts, 9, 15))
46+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 11, 20))
47+
>cb : Symbol(cb, Decl(implicitAnyGenericTypeInference.ts, 11, 23))
48+
>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --))
49+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 11, 20))
50+
51+
f2(async () => null);
52+
>f2 : Symbol(f2, Decl(implicitAnyGenericTypeInference.ts, 9, 15))
53+
54+
declare function f3<T>(cb: () => Generator<T>): void;
55+
>f3 : Symbol(f3, Decl(implicitAnyGenericTypeInference.ts, 12, 21))
56+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 14, 20))
57+
>cb : Symbol(cb, Decl(implicitAnyGenericTypeInference.ts, 14, 23))
58+
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
59+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 14, 20))
60+
61+
f3(function* () { yield null; });
62+
>f3 : Symbol(f3, Decl(implicitAnyGenericTypeInference.ts, 12, 21))
63+
64+
declare function f4<T>(cb: () => Generator<unknown, T>): void;
65+
>f4 : Symbol(f4, Decl(implicitAnyGenericTypeInference.ts, 15, 33))
66+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 17, 20))
67+
>cb : Symbol(cb, Decl(implicitAnyGenericTypeInference.ts, 17, 23))
68+
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
69+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 17, 20))
70+
71+
f4(function* () { return null; });
72+
>f4 : Symbol(f4, Decl(implicitAnyGenericTypeInference.ts, 15, 33))
73+
74+
declare function f5<T>(cb: () => AsyncGenerator<T>): void;
75+
>f5 : Symbol(f5, Decl(implicitAnyGenericTypeInference.ts, 18, 34))
76+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 20, 20))
77+
>cb : Symbol(cb, Decl(implicitAnyGenericTypeInference.ts, 20, 23))
78+
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
79+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 20, 20))
80+
81+
f5(async function* () { yield null; });
82+
>f5 : Symbol(f5, Decl(implicitAnyGenericTypeInference.ts, 18, 34))
83+
84+
declare function f6<T>(cb: () => AsyncGenerator<unknown, T>): void;
85+
>f6 : Symbol(f6, Decl(implicitAnyGenericTypeInference.ts, 21, 39))
86+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 23, 20))
87+
>cb : Symbol(cb, Decl(implicitAnyGenericTypeInference.ts, 23, 23))
88+
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
89+
>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 23, 20))
90+
91+
f6(async function* () { return null; });
92+
>f6 : Symbol(f6, Decl(implicitAnyGenericTypeInference.ts, 21, 39))
93+
94+
// https://github.com/microsoft/TypeScript/issues/44913
95+
Promise.resolve().catch(e => null);
96+
>Promise.resolve().catch : Symbol(Promise.catch, Decl(lib.es5.d.ts, --, --))
97+
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
98+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
99+
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
100+
>catch : Symbol(Promise.catch, Decl(lib.es5.d.ts, --, --))
101+
>e : Symbol(e, Decl(implicitAnyGenericTypeInference.ts, 27, 24))
102+
103+
Promise.resolve().then(v => null);
104+
>Promise.resolve().then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
105+
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
106+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
107+
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
108+
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
109+
>v : Symbol(v, Decl(implicitAnyGenericTypeInference.ts, 28, 23))
110+

0 commit comments

Comments
 (0)