
Ask HN: TypeScript experts, is this a type checking issue? - chupa-chups
The following ts code both compiles (with all checks active) and passes tslint without complaints:<p><pre><code>  type sig = (p: number) =&gt; string;
  const x = (p: any) =&gt; p + 1;
  const y: sig = x;
  alert(typeof y(5));
</code></pre>
Obviously the alert message will (and does) display &#x27;number&#x27;.<p>IntelliJ spots the problem though (&#x27;x&#x27; should probably not be assigned to &#x27;y&#x27;).<p>(Apologies if this is too stackoverflow-y, but I don&#x27;t expect a &quot;solution&quot;, I&#x27;m just interested in opinions)
======
n_e
any is assignable to anything so what you’re seeing here is the expected
behavior.

What I’d recommend is not to use any (and enable the linter rules to disable
it) and rather use unknown (which is assignable to nothing) or generics.

On a more general note, typescript is not sound (though it works well in
practice) and you’ll always be able to find incorrect code that typechecks,
even without using any.

~~~
chupa-chups
Thanks for the reply. I'm writing a ts parser and stumbled over this.

The reason I find it strange is that in this case it appears detectable that
the return type will not match (independent of the any type in the parameter).

Is there a reason not to check this I'm not seeing?

By the way, I am quite amazed at the quality (and depth) of the typescript
type inference & check model (despite it being "not sound" to quote you).

~~~
sbergot
The reason is that any is an escape mechanism. Typescript will never complain
about anything when dealing with this type. Its use case is to perform a step
by step migrations from js or to deal with rare corner cases when you can
prove yourself that the code is correct.

------
fr33104d
The type of x is (p: any) => any. It will be assignable to sig.

------
mikekchar
I don't know TS, but instead of alert(typeof y(5)) why not try alert(typeof
y('a')) I would hope you get a compile error. Looking at the code, I would
guess that the "any" means that it's essentially a parameterised type. In my
ideal world, it wouldn't mean that you can put literally any type in there at
any time -- just that you can put any type that will satisfy the type checker.
Because you are using it p as a number, it satisfies the type checker.

Another thing you can try is to pass x in as a parameter to a function. I
would expect that this would not compile -- because the compiler can't
guarantee (without jumping through incredible hoops) that x is always going to
use p as a number. If it _does_ compile, try to pass 2 functions: one
numerical and one that uses chars. If that compiles, then I think you have a
legitimate error in the type checker. Otherwise I think it's just fine.

~~~
chupa-chups
Sadly (but understandably) typeof is a runtime expression.

------
Vinnl
What would the problem be? If you use `any`, any code that touches that value
can no longer be properly type checked. The type of x is `(p: any) => any` (if
p is a string, p + 1 will return a string as well), so it can be assigned to y
just fine - at least as far as the type annotations are concerned.

------
aparadja
I think your original hunch is correct. This is a little too stackoverflow-y.

