Typescript: Exclamation mark next to operator does not produce compilation error.

Created on 16 Feb 2018  路  14Comments  路  Source: microsoft/TypeScript



TypeScript Version: 2.7.2


Search Terms:
is:issue label:Bug exclamation
Code

// actually any combination compiles !+, !<, !-
if (5 !> 2) {
    // Something
}
const result = 5 !+ 2;

Expected behavior:
Should be compilation error, same as it would be for 5 ~+ 2, 5 ?+ 2 or something similar.
Actual behavior:
Strips off "!" and compiles operator behind it.

Working as Intended

Most helpful comment

I hope nobody plans to port some this stuff from Typescript to C#

I think you mean, from C to C#...

using System;

public namespace App
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(~~~~~~~~~~~~~1); // -2
            var a = 1;
            var b = 1;
            Console.WriteLine(a++ +b); // 2
            a = 1;
            b = 1;
            Console.WriteLine(a + ++b); // 3
        }
    }
}

All 14 comments

The exclamation mark here is actually part of a non-null assertion. You basically assert that 5 is not null or undefined.
Consider the following:

declare let foo: number | undefined;
if (foo! > 2) { } // assertion is actually needed here, otherwise the compiler complains about possibly undefined value

If you want a warning when an assertion is unnecessary, you could use a lint rule:
TSLint has no-unnecessary-type-assertion (use with caution, sometimes the assertion is necessary but the linter still complains)
My linter project wotan has a rule no-useless-assertion that does a bit more than TSLint's rule and should also get the edge cases right.

Reminds me of the --> operator.

@ajafff: Example you have gave is OK foo! > 2, but having extra space in between like foo !> 2 or
foo ! > 2 being valid, does not seem right to me.

but having extra space in between like foo !> 2 or foo ! > 2 being valid, does not seem right to me.

This consistent with other post-expression notation; x .y or x [0] or x () or function f(x ?: string) { } are all valid.

@RyanCavanaugh Yes, I see your point. Unfortunately, some of those post-expression cases are more confusing then the others.

@andy-ms Am I wrong, or is this only case where a !== b and a ! == b compile in two different things?

This also compiles a!!!!!==b. I don't know. It feels odd.

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@nenadvicentic a ! == b isn't valid JS -- you can't insert spaces in the middle of an operator.

@andy-ms Both expression are valid in Typescript. Now extra space char can produce different valid expression. Also, only operator you can chain on itself a!!!!!.

@nenadvicentic you forget ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1

JS also has expressions whose meaning varies based on spacing:

let a = 1;
let b = 1;
console.log(a++ +b); // 2, but `a+ ++b` is 3

@weswigham, @andy-ms Good point, I did not know about ~~ thing. 馃槼 Both examples are correct. I guess I'll switch back to C#.

P.S. Damn, I hope nobody plans to port some this stuff from Typescript to C#. 馃槸

I hope nobody plans to port some this stuff from Typescript to C#

I think you mean, from C to C#...

using System;

public namespace App
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(~~~~~~~~~~~~~1); // -2
            var a = 1;
            var b = 1;
            Console.WriteLine(a++ +b); // 2
            a = 1;
            b = 1;
            Console.WriteLine(a + ++b); // 3
        }
    }
}

Are there any languages that disallow repeated applications of the same prefix unary operator?

@andy-ms No, I was aiming at non-nullable classes.
@RyanCavanaugh : ++++a does not seem to work. Only postfix operator that can be chained seems to be !.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MartynasZilinskas picture MartynasZilinskas  路  3Comments

wmaurer picture wmaurer  路  3Comments

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

seanzer picture seanzer  路  3Comments

bgrieder picture bgrieder  路  3Comments