0
let a;
a = 5;
a = "hi";

Why this is valid TypeScript code? Are there any settings to stricter that besides «a:number»? If not, then what's the point of using TypeScipt, if you can use JavaScript + vscode //@ts-check? My tsconfig.json:

"compilerOptions": {
 "baseUrl": ".",
 "outDir": "build/dist",
 "module": "esnext",
 "target": "es6",
 "lib": ["es6", "dom"],
 "sourceMap": true,
 "allowJs": false,
 "strict": true,
 "jsx": "react",
 "moduleResolution": "node",
 "rootDir": "src",
 "forceConsistentCasingInFileNames": true,
 "noImplicitReturns": true,
 "noImplicitThis": true,
 "noImplicitAny": true,
 "strictNullChecks": true,
 "suppressImplicitAnyIndexErrors": true,
 "noUnusedLocals": true
},
PlayMa256
6,8612 gold badges40 silver badges58 bronze badges
asked May 24, 2018 at 15:56
4
  • 1
    That is completly weird, i agree... it is being infeered as as Any, but you have noImplicityAny... Commented May 24, 2018 at 15:59
  • Can I ask how typescript is supposed to know it is a number or string? shouldn't you be declaring it to be a number so you do not run into it? let a: number Commented May 24, 2018 at 16:01
  • @epascarello in my opinion there should be error=warning like «a has any type» Commented May 24, 2018 at 16:10
  • The compiler knows through static flow analisys. After the last line, the variable is always a string underneath, even if it disguised as any Commented May 24, 2018 at 16:37

3 Answers 3

5

It works because noImplicitAny does not affect variable declarations. If a variable is declared, but it's type is not declared, it is assumed any.

This was defined like that, because the compiler, despite the variable being any implicitly, can in fact determine its type at every point.

In fact, if you do this:

var a;
a = 5;
a.dot(); // error, number does not have a 'dot' property.
a = "hi";
a.foo(); // error, string does not have a 'foo' property.

You get an error, indicating that string has no property foo, or number has no property dot.

But, if you write:

function(b) {
 return b + 2;
}

This function, however, indicates an error because there is nothing that hints the compiler about what type b holds.

answered May 24, 2018 at 16:05
Sign up to request clarification or add additional context in comments.

3 Comments

When did this change? Presumably with better flow analysis? I can remember getting "implicit any" errors for variables and can even get them when using typescript 1.8. For typescript 2.8 and the same code, there is no error as described here.
I guess i found it: improved any inference, typescript 2.1.
Yes. It changed around 2.1 or so. There was a PR about this. If the type can be determined by flow analisys, then there is not really an implicit any, even i f the variable can take any value of any type. As long as the type can be determined for every line of code in whuch it appears, there won't be an error.
3

Why this is valid TypeScript code?

To allow backwards compability with javascript. This is completely valid js, so it needs to be valid typescript too. But you can easily opt in typechecking:

let a: number;
answered May 24, 2018 at 16:01

4 Comments

By the way I cant understand typescript philosophy here. There are almost no differences between TypeScript types checking and raw js with //@ts-checking in VSCode
That would be true, if the OP didn't have notImplicitAny turned on. notImplicitAny increases the type safety of your code, but diminishes the compatibility with the existing codebase
@foxPro well there are interfaces and enums, and the typechecking goes far beyond these simple cases
@OscarPaz you are right, but the notImplicitAny affects function arguments and not variables.
2

Why this is valid TypeScript code?

noImplicityAny only affects "arguments" not "variables".

Consequently this codes is correct:

let a;
a = 'test';
a = 123;

But you will get an error, when you want to declare a functions argument:

function log(someArg) { // Error : someArg has an implicit `any` type
 console.log(someArg);
} 

This code would work:

function log(someArg: any | string | number) { // Error : someArg has an implicit `any` type
 console.log(someArg);
} 

TypeScript ensures, that you can use types and validates them, when the variable is in use (eg. as an argument).

Here you can find the article.

answered May 24, 2018 at 16:13

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.