diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7f05c9b40df..78cee25efc9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27381,6 +27381,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isFunctionObjectType(type: ObjectType): boolean { + if (getObjectFlags(type) & ObjectFlags.EvolvingArray) { + return false; + } // We do a quick check for a "bind" property before performing the more expensive subtype // check. This gives us a quicker out in the common case where an object type is not a function. const resolved = resolveStructuredTypeMembers(type); diff --git a/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.errors.txt b/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.errors.txt new file mode 100644 index 00000000000..d503ac8d760 --- /dev/null +++ b/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.errors.txt @@ -0,0 +1,25 @@ +narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts(1,5): error TS7034: Variable 'foo' implicitly has type 'any[]' in some locations where its type cannot be determined. +narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts(5,5): error TS7005: Variable 'foo' implicitly has an 'any[]' type. + + +==== narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts (2 errors) ==== + let foo = []; + ~~~ +!!! error TS7034: Variable 'foo' implicitly has type 'any[]' in some locations where its type cannot be determined. + + switch (foo?.length) { + case 1: + foo[0]; + ~~~ +!!! error TS7005: Variable 'foo' implicitly has an 'any[]' type. + } + + let bar = []; + + switch (bar?.length) { + case 1: { + bar.push("baz"); + const arr: string[] = bar; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.symbols b/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.symbols new file mode 100644 index 00000000000..d766eadf659 --- /dev/null +++ b/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.symbols @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts] //// + +=== narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts === +let foo = []; +>foo : Symbol(foo, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 0, 3)) + +switch (foo?.length) { +>foo?.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>foo : Symbol(foo, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 0, 3)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) + + case 1: + foo[0]; +>foo : Symbol(foo, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 0, 3)) +} + +let bar = []; +>bar : Symbol(bar, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 7, 3)) + +switch (bar?.length) { +>bar?.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>bar : Symbol(bar, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 7, 3)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) + + case 1: { + bar.push("baz"); +>bar.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>bar : Symbol(bar, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 7, 3)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) + + const arr: string[] = bar; +>arr : Symbol(arr, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 12, 9)) +>bar : Symbol(bar, Decl(narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts, 7, 3)) + } +} + diff --git a/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.types b/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.types new file mode 100644 index 00000000000..0a5d8998007 --- /dev/null +++ b/tests/baselines/reference/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.types @@ -0,0 +1,68 @@ +//// [tests/cases/compiler/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts] //// + +=== narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts === +let foo = []; +>foo : any[] +> : ^^^^^ +>[] : never[] +> : ^^^^^^^ + +switch (foo?.length) { +>foo?.length : number +> : ^^^^^^ +>foo : any[] +> : ^^^^^ +>length : number +> : ^^^^^^ + + case 1: +>1 : 1 +> : ^ + + foo[0]; +>foo[0] : any +> : ^^^ +>foo : any[] +> : ^^^^^ +>0 : 0 +> : ^ +} + +let bar = []; +>bar : any[] +> : ^^^^^ +>[] : never[] +> : ^^^^^^^ + +switch (bar?.length) { +>bar?.length : number +> : ^^^^^^ +>bar : any[] +> : ^^^^^ +>length : number +> : ^^^^^^ + + case 1: { +>1 : 1 +> : ^ + + bar.push("baz"); +>bar.push("baz") : number +> : ^^^^^^ +>bar.push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>bar : any[] +> : ^^^^^ +>push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>"baz" : "baz" +> : ^^^^^ + + const arr: string[] = bar; +>arr : string[] +> : ^^^^^^^^ +>bar : string[] +> : ^^^^^^^^ + } +} + diff --git a/tests/cases/compiler/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts b/tests/cases/compiler/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts new file mode 100644 index 00000000000..d20c1c1160f --- /dev/null +++ b/tests/cases/compiler/narrowSwitchOptionalChainContainmentEvolvingArrayNoCrash1.ts @@ -0,0 +1,18 @@ +// @strict: true +// @noEmit: true + +let foo = []; + +switch (foo?.length) { + case 1: + foo[0]; +} + +let bar = []; + +switch (bar?.length) { + case 1: { + bar.push("baz"); + const arr: string[] = bar; + } +}