There's a few questions around implicit any
types in Typescript but none that I've found answer my question.
Say I have this:
let thing;
thing = 'someValue';
thing = 'someOtherValue';
The variable thing
will now have the type any
.
How can I prevent this situation where a variable is declared without a type annotation AND without being immediately assigned a value with a concrete type? I'm using ESLint and found the rule @typescript-eslint/no-unsafe-assignment
but that doesn't cover this case.
PLEASE NOTE the suggested duplicate doesn't really answer my question. I already have strict
enabled in the TS compiler options, which causes noImplicitAny
to also be enabled, however noImplicitAny
doesn't do enough for me.
What I want is to not be allowed to create a variable of type any
except by explicitly annotating the type as any
. It's very inconvenient that a variable created near the top of a block can have its type inferred many lines further down AND in multiple places, meaning my IDE can't tell me the type until after I've used the variable. I would much rather that my types must be declared at the time I create the variable.
Examples:
// Good
let thing: string;
...
thing = 'someValue';
// Good
let thing = 'someValue';
// Good
let thing = SomeFunctionWithAnnotatedReturnType();
// Bad
// This is what I want to prevent
let thing;
...
thing = '123';
...
thing = 123;
After discussions between many people and much googling, I eventually proposed a Typescript ESLint rule. To my great surprise, what I want is already possible with the following ESLint rule, seen working here:
"no-restricted-syntax": [
"error",
{
"selector": "VariableDeclaration[kind = 'let'] > VariableDeclarator[init = null]:not([id.typeAnnotation])",
"message": "Type must be inferred at variable declaration"
}
]
I didn't know that was possible and it opens up a whole lot more possibilities.