Typescript: New asserts syntax fails with arrow functions

Created on 25 Sep 2019  路  4Comments  路  Source: microsoft/TypeScript

The new assertions in control flow analysis (see #32695) feature fails to work when the assert function is defined as an arrow function (i.e. defined using const or let).


TypeScript Version: 3.7.0-dev.20190925


Search Terms:
Assertions in control flow analysis

Code

const assert0 = (input: unknown): asserts input => {}
function assert1(input: unknown): asserts input {}

declare const assert2: (input: unknown) => asserts input
declare function assert3(input: unknown): asserts input

const inputFunction = (input: number) => {}

const test = (x: unknown, y: unknown, z: unknown, w: unknown) => {
    assert0(typeof x === "number")
    x // VSCode intellisense says the type of x is still unknown here
    inputFunction(x)

    assert1(typeof y === "number")
    y // VSCode intellisense says y is number, which is expected
    inputFunction(y)

    assert2(typeof z === "number")
    z // VSCode intellisense says z is number, which is expected
    inputFunction(z)

    assert3(typeof w === "number")
    w // VSCode intellisense says w is number, which is expected
    inputFunction(w)
}

Expected behavior:
x, y, z, w should all have the type number after the respective assertion.

Actual behavior:
x remains as unknown. This behavior is exhibited both in VSCode's type preview (see here: https://i.imgur.com/04uJTor.png) and as a compile error when we call inputFunction(x). The tsc error output is shown below:

index.ts:12:19 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'number'.

12     inputFunction(x)
                     ~


Found 1 error.

Playground Link:
Playground's "nightly" version doesn't support the asserts syntax.

Related Issues:
N/A

Duplicate

Most helpful comment

See related discussion here: #33580

All 4 comments

@lppedd was playing around with this in Gitter and noticed that the following works:

const assert0: (input: any) => asserts input is number = (input: any): asserts input is number => {};

It seems that just explicitly specifying the type makes it work.

const assert0: (input: unknown) => asserts input = (input: unknown): asserts input => {};

See related discussion here: #33580

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

uber5001 picture uber5001  路  3Comments

jbondc picture jbondc  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

dlaberge picture dlaberge  路  3Comments

weswigham picture weswigham  路  3Comments