Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28708,6 +28708,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const links = getNodeLinks(node);
let signature = links.effectsSignature;
if (signature === undefined) {
links.effectsSignature = unknownSignature;
// A call expression parented by an expression statement is a potential assertion. Other call
// expressions are potential type predicate function calls. In order to avoid triggering
// circularities in control flow analysis, we use getTypeOfDottedName when resolving the call
Expand Down
55 changes: 55 additions & 0 deletions tests/baselines/reference/controlFlowForFunctionLike1.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
controlFlowForFunctionLike1.ts(10,12): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
controlFlowForFunctionLike1.ts(21,12): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
controlFlowForFunctionLike1.ts(31,10): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.


==== controlFlowForFunctionLike1.ts (3 errors) ====
function test1(a: number | string) {
if (typeof a === "number") {
const fn = (arg: typeof a) => true;
return fn;
}
return;
}

test1(0)?.(100);
test1(0)?.("");
~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

function test2(a: number | string) {
if (typeof a === "number") {
const fn: { (arg: typeof a): boolean; } = () => true;
return fn;
}
return;
}

test2(0)?.(100);
test2(0)?.("");
~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

function test3(a: number | string) {
if (typeof a === "number") {
return (arg: typeof a) => {};
}
throw new Error("");
}

test3(1)(100);
test3(1)("");
~~
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

function test4(a: number | string) {
let fn = (arg: typeof a) => {};
if (Math.random() && typeof a === "number") {
return fn;
}
throw new Error("");
}

test4(1)?.(100);
test4(1)?.("");

100 changes: 100 additions & 0 deletions tests/baselines/reference/controlFlowForFunctionLike1.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//// [tests/cases/compiler/controlFlowForFunctionLike1.ts] ////

=== controlFlowForFunctionLike1.ts ===
function test1(a: number | string) {
>test1 : Symbol(test1, Decl(controlFlowForFunctionLike1.ts, 0, 0))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 0, 15))

if (typeof a === "number") {
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 0, 15))

const fn = (arg: typeof a) => true;
>fn : Symbol(fn, Decl(controlFlowForFunctionLike1.ts, 2, 9))
>arg : Symbol(arg, Decl(controlFlowForFunctionLike1.ts, 2, 16))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 0, 15))

return fn;
>fn : Symbol(fn, Decl(controlFlowForFunctionLike1.ts, 2, 9))
}
return;
}

test1(0)?.(100);
>test1 : Symbol(test1, Decl(controlFlowForFunctionLike1.ts, 0, 0))

test1(0)?.("");
>test1 : Symbol(test1, Decl(controlFlowForFunctionLike1.ts, 0, 0))

function test2(a: number | string) {
>test2 : Symbol(test2, Decl(controlFlowForFunctionLike1.ts, 9, 15))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 11, 15))

if (typeof a === "number") {
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 11, 15))

const fn: { (arg: typeof a): boolean; } = () => true;
>fn : Symbol(fn, Decl(controlFlowForFunctionLike1.ts, 13, 9))
>arg : Symbol(arg, Decl(controlFlowForFunctionLike1.ts, 13, 17))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 11, 15))

return fn;
>fn : Symbol(fn, Decl(controlFlowForFunctionLike1.ts, 13, 9))
}
return;
}

test2(0)?.(100);
>test2 : Symbol(test2, Decl(controlFlowForFunctionLike1.ts, 9, 15))

test2(0)?.("");
>test2 : Symbol(test2, Decl(controlFlowForFunctionLike1.ts, 9, 15))

function test3(a: number | string) {
>test3 : Symbol(test3, Decl(controlFlowForFunctionLike1.ts, 20, 15))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 22, 15))

if (typeof a === "number") {
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 22, 15))

return (arg: typeof a) => {};
>arg : Symbol(arg, Decl(controlFlowForFunctionLike1.ts, 24, 12))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 22, 15))
}
throw new Error("");
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

test3(1)(100);
>test3 : Symbol(test3, Decl(controlFlowForFunctionLike1.ts, 20, 15))

test3(1)("");
>test3 : Symbol(test3, Decl(controlFlowForFunctionLike1.ts, 20, 15))

function test4(a: number | string) {
>test4 : Symbol(test4, Decl(controlFlowForFunctionLike1.ts, 30, 13))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 32, 15))

let fn = (arg: typeof a) => {};
>fn : Symbol(fn, Decl(controlFlowForFunctionLike1.ts, 33, 5))
>arg : Symbol(arg, Decl(controlFlowForFunctionLike1.ts, 33, 12))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 32, 15))

if (Math.random() && typeof a === "number") {
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(controlFlowForFunctionLike1.ts, 32, 15))

return fn;
>fn : Symbol(fn, Decl(controlFlowForFunctionLike1.ts, 33, 5))
}
throw new Error("");
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

test4(1)?.(100);
>test4 : Symbol(test4, Decl(controlFlowForFunctionLike1.ts, 30, 13))

test4(1)?.("");
>test4 : Symbol(test4, Decl(controlFlowForFunctionLike1.ts, 30, 13))

Loading