I usually have the following code:
class Foo {
foo: SomeType[];
doSomething() {
const a = this.foo = [];
}
}
In this case, a
would be any[]
or never[]
(depends on environment) instead of SomeType[]
. If I specify noImplicitAny
on those that imply any[]
, the compiler would throw an error.
I know the below cast fixes the problem, but why can't TypeScript deduce the type from this.foo
?
const a: SomeType[] = this.foo = []; // Have to repeat the type again
Reproducible code:
tsconfig.json
:
{
"compilerOptions": {
"noImplicitAny": true
}
}
test.ts
:
class Foo {
foo: number[];
doSomething() {
const a = this.foo = [];
}
}
The type being inferred as any[]
makes sense because Javascript is right-associative wrt the assignment
operator.
See this question: Multiple left-hand assignment with JavaScript
This means that the expression:
const a = this.foo = [];
Is interpreted as:
this.foo = [];
const a = [];
As you can see, the type information isn't associated with empty array, so any[]
is the most correct type.
You can prove this is in fact what is happening with a simple example:
let t: number;
const a = t = 5;
The inferred type for a
would be the literal number 5
, not number
(which is the type for t
).
It seems that the typescript playground may be wrong in this case, which is why many (including myself) are reporting never[]
as the inferred type.