diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c12310ea267f2..168a996269aea 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20633,7 +20633,7 @@ namespace ts { // we defer subtype reduction until the evolving array type is finalized into a manifest // array type. function addEvolvingArrayElementType(evolvingArrayType: EvolvingArrayType, node: Expression): EvolvingArrayType { - const elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node)); + const elementType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node))); return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType])); } diff --git a/tests/baselines/reference/controlFlowArrays.js b/tests/baselines/reference/controlFlowArrays.js index 73ac8932f7be4..864f28e4f228e 100644 --- a/tests/baselines/reference/controlFlowArrays.js +++ b/tests/baselines/reference/controlFlowArrays.js @@ -176,7 +176,16 @@ function f18() { x.unshift("hello"); x[2] = true; return x; // (string | number | boolean)[] -} +} + +// Repro from #39470 + +declare function foo(arg: { val: number }[]): void; + +let arr = [] +arr.push({ val: 1, bar: 2 }); +foo(arr); + //// [controlFlowArrays.js] function f1() { @@ -340,3 +349,6 @@ function f18() { x[2] = true; return x; // (string | number | boolean)[] } +var arr = []; +arr.push({ val: 1, bar: 2 }); +foo(arr); diff --git a/tests/baselines/reference/controlFlowArrays.symbols b/tests/baselines/reference/controlFlowArrays.symbols index 25e5ef01bcfb7..b36020031dde8 100644 --- a/tests/baselines/reference/controlFlowArrays.symbols +++ b/tests/baselines/reference/controlFlowArrays.symbols @@ -467,3 +467,25 @@ function f18() { return x; // (string | number | boolean)[] >x : Symbol(x, Decl(controlFlowArrays.ts, 172, 7)) } + +// Repro from #39470 + +declare function foo(arg: { val: number }[]): void; +>foo : Symbol(foo, Decl(controlFlowArrays.ts, 177, 1)) +>arg : Symbol(arg, Decl(controlFlowArrays.ts, 181, 21)) +>val : Symbol(val, Decl(controlFlowArrays.ts, 181, 27)) + +let arr = [] +>arr : Symbol(arr, Decl(controlFlowArrays.ts, 183, 3)) + +arr.push({ val: 1, bar: 2 }); +>arr.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arr : Symbol(arr, Decl(controlFlowArrays.ts, 183, 3)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>val : Symbol(val, Decl(controlFlowArrays.ts, 184, 10)) +>bar : Symbol(bar, Decl(controlFlowArrays.ts, 184, 18)) + +foo(arr); +>foo : Symbol(foo, Decl(controlFlowArrays.ts, 177, 1)) +>arr : Symbol(arr, Decl(controlFlowArrays.ts, 183, 3)) + diff --git a/tests/baselines/reference/controlFlowArrays.types b/tests/baselines/reference/controlFlowArrays.types index 6dbddbda075fc..80d1e3484770b 100644 --- a/tests/baselines/reference/controlFlowArrays.types +++ b/tests/baselines/reference/controlFlowArrays.types @@ -612,3 +612,31 @@ function f18() { return x; // (string | number | boolean)[] >x : (string | number | boolean)[] } + +// Repro from #39470 + +declare function foo(arg: { val: number }[]): void; +>foo : (arg: { val: number;}[]) => void +>arg : { val: number; }[] +>val : number + +let arr = [] +>arr : any[] +>[] : never[] + +arr.push({ val: 1, bar: 2 }); +>arr.push({ val: 1, bar: 2 }) : number +>arr.push : (...items: any[]) => number +>arr : any[] +>push : (...items: any[]) => number +>{ val: 1, bar: 2 } : { val: number; bar: number; } +>val : number +>1 : 1 +>bar : number +>2 : 2 + +foo(arr); +>foo(arr) : void +>foo : (arg: { val: number; }[]) => void +>arr : { val: number; bar: number; }[] + diff --git a/tests/cases/compiler/controlFlowArrays.ts b/tests/cases/compiler/controlFlowArrays.ts index 646c85f069f89..786b61aea211b 100644 --- a/tests/cases/compiler/controlFlowArrays.ts +++ b/tests/cases/compiler/controlFlowArrays.ts @@ -178,4 +178,12 @@ function f18() { x.unshift("hello"); x[2] = true; return x; // (string | number | boolean)[] -} \ No newline at end of file +} + +// Repro from #39470 + +declare function foo(arg: { val: number }[]): void; + +let arr = [] +arr.push({ val: 1, bar: 2 }); +foo(arr);