Skip to content

Commit 2877b6f

Browse files
authored
Issue implicit any in JS files on widened inferred types from initializers in binding patterns (#1064)
1 parent 2e0f7e9 commit 2877b6f

9 files changed

+88
-160
lines changed

internal/checker/checker.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16092,6 +16092,21 @@ func (c *Checker) padTupleType(t *Type, pattern *ast.Node) *Type {
1609216092
}
1609316093

1609416094
func (c *Checker) widenTypeInferredFromInitializer(declaration *ast.Node, t *Type) *Type {
16095+
widened := c.getWidenedLiteralTypeForInitializer(declaration, t)
16096+
if ast.IsInJSFile(declaration) {
16097+
if c.isEmptyLiteralType(widened) {
16098+
c.reportImplicitAny(declaration, c.anyType, WideningKindNormal)
16099+
return c.anyType
16100+
}
16101+
if c.isEmptyArrayLiteralType(widened) {
16102+
c.reportImplicitAny(declaration, c.anyArrayType, WideningKindNormal)
16103+
return c.anyArrayType
16104+
}
16105+
}
16106+
return widened
16107+
}
16108+
16109+
func (c *Checker) getWidenedLiteralTypeForInitializer(declaration *ast.Node, t *Type) *Type {
1609516110
if c.getCombinedNodeFlagsCached(declaration)&ast.NodeFlagsConstant != 0 || isDeclarationReadonly(declaration) {
1609616111
return t
1609716112
}
@@ -17212,7 +17227,7 @@ func (c *Checker) getTypeFromBindingElement(element *ast.Node, includePatternInT
1721217227
if ast.IsBindingPattern(element.Name()) {
1721317228
contextualType = c.getTypeFromBindingPattern(element.Name(), true /*includePatternInType*/, false /*reportErrors*/)
1721417229
}
17215-
return c.addOptionality(c.widenTypeInferredFromInitializer(element, c.checkDeclarationInitializer(element, CheckModeNormal, contextualType)))
17230+
return c.addOptionality(c.getWidenedLiteralTypeForInitializer(element, c.checkDeclarationInitializer(element, CheckModeNormal, contextualType)))
1721617231
}
1721717232
if ast.IsBindingPattern(element.Name()) {
1721817233
return c.getTypeFromBindingPattern(element.Name(), includePatternInType, reportErrors)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
index.js(15,9): error TS7031: Binding element 'json' implicitly has an 'any[]' type.
2+
3+
4+
==== index.js (1 errors) ====
5+
/**
6+
* @param {Object} [config]
7+
* @param {Partial<Record<'json' | 'jsonc' | 'json5', string[]>>} [config.additionalFiles]
8+
*/
9+
export function prepareConfig({
10+
additionalFiles: {
11+
json = []
12+
} = {}
13+
} = {}) {
14+
json // string[]
15+
}
16+
17+
export function prepareConfigWithoutAnnotation({
18+
additionalFiles: {
19+
json = []
20+
~~~~
21+
!!! error TS7031: Binding element 'json' implicitly has an 'any[]' type.
22+
} = {}
23+
} = {}) {
24+
json
25+
}
26+
27+
/** @type {(param: {
28+
additionalFiles?: Partial<Record<"json" | "jsonc" | "json5", string[]>>;
29+
}) => void} */
30+
export const prepareConfigWithContextualSignature = ({
31+
additionalFiles: {
32+
json = []
33+
} = {}
34+
} = {})=> {
35+
json // string[]
36+
}
37+
38+
// Additional repros from https://github.com/microsoft/TypeScript/issues/59936
39+
40+
/**
41+
* @param {{ a?: { json?: string[] }}} [config]
42+
*/
43+
function f1({ a: { json = [] } = {} } = {}) { return json }
44+
45+
/**
46+
* @param {[[string[]?]?]} [x]
47+
*/
48+
function f2([[json = []] = []] = []) { return json }
49+

testdata/baselines/reference/submodule/conformance/destructuringParameterDeclaration9(strict=true).types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function prepareConfigWithoutAnnotation({
3232
>additionalFiles : any
3333

3434
json = []
35-
>json : never[]
35+
>json : any[]
3636
>[] : never[]
3737

3838
} = {}
@@ -42,7 +42,7 @@ export function prepareConfigWithoutAnnotation({
4242
>{} : {}
4343

4444
json
45-
>json : never[]
45+
>json : any[]
4646
}
4747

4848
/** @type {(param: {

testdata/baselines/reference/submodule/conformance/typeFromJSInitializer.errors.txt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
a.js(7,9): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.
2+
a.js(25,29): error TS7006: Parameter 'l' implicitly has an 'any[]' type.
23
a.js(27,5): error TS2322: Type 'undefined' is not assignable to type 'null'.
34
a.js(29,5): error TS2322: Type '1' is not assignable to type 'null'.
45
a.js(30,5): error TS2322: Type 'true' is not assignable to type 'null'.
56
a.js(31,5): error TS2322: Type '{}' is not assignable to type 'null'.
67
a.js(32,5): error TS2322: Type '"ok"' is not assignable to type 'null'.
78
a.js(37,5): error TS2322: Type 'string' is not assignable to type 'number'.
8-
a.js(40,12): error TS2345: Argument of type '1' is not assignable to parameter of type 'never'.
9-
a.js(41,12): error TS2345: Argument of type '"ok"' is not assignable to parameter of type 'never'.
109

1110

12-
==== a.js (9 errors) ====
11+
==== a.js (8 errors) ====
1312
function A () {
1413
// should get any on this-assignments in constructor
1514
this.unknown = null
@@ -37,6 +36,8 @@ a.js(41,12): error TS2345: Argument of type '"ok"' is not assignable to paramete
3736

3837
// should get any on parameter initialisers
3938
function f(a = null, b = n, l = []) {
39+
~~~~~~
40+
!!! error TS7006: Parameter 'l' implicitly has an 'any[]' type.
4041
// a should be null in strict mode
4142
a = undefined
4243
~
@@ -64,11 +65,7 @@ a.js(41,12): error TS2345: Argument of type '"ok"' is not assignable to paramete
6465

6566
// l should be any[]
6667
l.push(1)
67-
~
68-
!!! error TS2345: Argument of type '1' is not assignable to parameter of type 'never'.
6968
l.push('ok')
70-
~~~~
71-
!!! error TS2345: Argument of type '"ok"' is not assignable to parameter of type 'never'.
7269
}
7370

7471
// should get any on variable initialisers

testdata/baselines/reference/submodule/conformance/typeFromJSInitializer.types

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,11 @@ var n;
128128

129129
// should get any on parameter initialisers
130130
function f(a = null, b = n, l = []) {
131-
>f : (a?: null, b?: number | undefined, l?: never[]) => void
131+
>f : (a?: null, b?: number | undefined, l?: any[]) => void
132132
>a : null
133133
>b : number | undefined
134134
>n : number | undefined
135-
>l : never[]
135+
>l : any[]
136136
>[] : never[]
137137

138138
// a should be null in strict mode
@@ -184,16 +184,16 @@ function f(a = null, b = n, l = []) {
184184
// l should be any[]
185185
l.push(1)
186186
>l.push(1) : number
187-
>l.push : (...items: never[]) => number
188-
>l : never[]
189-
>push : (...items: never[]) => number
187+
>l.push : (...items: any[]) => number
188+
>l : any[]
189+
>push : (...items: any[]) => number
190190
>1 : 1
191191

192192
l.push('ok')
193193
>l.push('ok') : number
194-
>l.push : (...items: never[]) => number
195-
>l : never[]
196-
>push : (...items: never[]) => number
194+
>l.push : (...items: any[]) => number
195+
>l : any[]
196+
>push : (...items: any[]) => number
197197
>'ok' : "ok"
198198
}
199199

testdata/baselines/reference/submoduleAccepted/conformance/destructuringParameterDeclaration9(strict=true).errors.txt.diff

Lines changed: 0 additions & 53 deletions
This file was deleted.

testdata/baselines/reference/submoduleAccepted/conformance/destructuringParameterDeclaration9(strict=true).types.diff

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,7 @@
99

1010
additionalFiles: {
1111
>additionalFiles : any
12-
@@= skipped -26, +26 lines =@@
13-
>additionalFiles : any
14-
15-
json = []
16-
->json : any[]
17-
+>json : never[]
18-
>[] : never[]
19-
20-
} = {}
21-
@@= skipped -10, +10 lines =@@
22-
>{} : {}
23-
24-
json
25-
->json : any[]
26-
+>json : never[]
27-
}
28-
29-
/** @type {(param: {
12+
@@= skipped -43, +43 lines =@@
3013
additionalFiles?: Partial<Record<"json" | "jsonc" | "json5", string[]>>;
3114
}) => void} */
3215
export const prepareConfigWithContextualSignature = ({
@@ -37,7 +20,7 @@
3720

3821
additionalFiles: {
3922
>additionalFiles : any
40-
@@= skipped -33, +33 lines =@@
23+
@@= skipped -26, +26 lines =@@
4124
* @param {{ a?: { json?: string[] }}} [config]
4225
*/
4326
function f1({ a: { json = [] } = {} } = {}) { return json }

testdata/baselines/reference/submoduleAccepted/conformance/typeFromJSInitializer.errors.txt.diff

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,16 @@
44
-a.js(3,5): error TS7008: Member 'unknown' implicitly has an 'any' type.
55
-a.js(4,5): error TS7008: Member 'unknowable' implicitly has an 'any' type.
66
-a.js(5,5): error TS7008: Member 'empty' implicitly has an 'any[]' type.
7-
-a.js(25,29): error TS7006: Parameter 'l' implicitly has an 'any[]' type.
87
+a.js(7,9): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.
8+
a.js(25,29): error TS7006: Parameter 'l' implicitly has an 'any[]' type.
99
a.js(27,5): error TS2322: Type 'undefined' is not assignable to type 'null'.
1010
a.js(29,5): error TS2322: Type '1' is not assignable to type 'null'.
11-
a.js(30,5): error TS2322: Type 'true' is not assignable to type 'null'.
12-
a.js(31,5): error TS2322: Type '{}' is not assignable to type 'null'.
13-
a.js(32,5): error TS2322: Type '"ok"' is not assignable to type 'null'.
11+
@@= skipped -9, +7 lines =@@
1412
a.js(37,5): error TS2322: Type 'string' is not assignable to type 'number'.
15-
-
16-
-
13+
14+
1715
-==== a.js (10 errors) ====
18-
+a.js(40,12): error TS2345: Argument of type '1' is not assignable to parameter of type 'never'.
19-
+a.js(41,12): error TS2345: Argument of type '"ok"' is not assignable to parameter of type 'never'.
20-
+
21-
+
22-
+==== a.js (9 errors) ====
16+
+==== a.js (8 errors) ====
2317
function A () {
2418
// should get any on this-assignments in constructor
2519
this.unknown = null
@@ -37,25 +31,4 @@
3731
+!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.
3832
a.unknown = 1
3933
a.unknown = true
40-
a.unknown = {}
41-
@@= skipped -41, +36 lines =@@
42-
43-
// should get any on parameter initialisers
44-
function f(a = null, b = n, l = []) {
45-
- ~~~~~~
46-
-!!! error TS7006: Parameter 'l' implicitly has an 'any[]' type.
47-
// a should be null in strict mode
48-
a = undefined
49-
~
50-
@@= skipped -29, +27 lines =@@
51-
52-
// l should be any[]
53-
l.push(1)
54-
+ ~
55-
+!!! error TS2345: Argument of type '1' is not assignable to parameter of type 'never'.
56-
l.push('ok')
57-
+ ~~~~
58-
+!!! error TS2345: Argument of type '"ok"' is not assignable to parameter of type 'never'.
59-
}
60-
61-
// should get any on variable initialisers
34+
a.unknown = {}

testdata/baselines/reference/submoduleAccepted/conformance/typeFromJSInitializer.types.diff

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -163,40 +163,4 @@
163163
+>push : any
164164
>'hi' : "hi"
165165

166-
/** @type {number | undefined} */
167-
@@= skipped -126, +126 lines =@@
168-
169-
// should get any on parameter initialisers
170-
function f(a = null, b = n, l = []) {
171-
->f : (a?: null, b?: number | undefined, l?: any[]) => void
172-
+>f : (a?: null, b?: number | undefined, l?: never[]) => void
173-
>a : null
174-
>b : number | undefined
175-
>n : number | undefined
176-
->l : any[]
177-
+>l : never[]
178-
>[] : never[]
179-
180-
// a should be null in strict mode
181-
@@= skipped -56, +56 lines =@@
182-
// l should be any[]
183-
l.push(1)
184-
>l.push(1) : number
185-
->l.push : (...items: any[]) => number
186-
->l : any[]
187-
->push : (...items: any[]) => number
188-
+>l.push : (...items: never[]) => number
189-
+>l : never[]
190-
+>push : (...items: never[]) => number
191-
>1 : 1
192-
193-
l.push('ok')
194-
>l.push('ok') : number
195-
->l.push : (...items: any[]) => number
196-
->l : any[]
197-
->push : (...items: any[]) => number
198-
+>l.push : (...items: never[]) => number
199-
+>l : never[]
200-
+>push : (...items: never[]) => number
201-
>'ok' : "ok"
202-
}
166+
/** @type {number | undefined} */

0 commit comments

Comments
 (0)