Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type inference vs. explicit type declaration in Typescript

I've come across several different instances of code where variables are declared with an explicit type even though the inferred type is obvious:

Example: loading: boolean = false or name: string = "John" or count: number = 0 etc.

TSLint favors the inferred type over the explicit type, so I'm wondering is this just a stylistic issue? Do these explicit types even matter during runtime?

like image 464
yoonjesung Avatar asked Aug 28 '17 03:08

yoonjesung


People also ask

What is type inference in TypeScript?

The type of the x variable is inferred to be number . This kind of inference takes place when initializing variables and members, setting parameter default values, and determining function return types. In most cases, type inference is straightforward.

What is explicit type in TypeScript?

Implicit types come from TypeScript inferring the type based on a variable's initial value and look just like regular JavaScript. Explicit types are when we intentionally provide the type using a special TypeScript syntax.

What are the different types of TypeScript?

TypeScript has two special types, null and undefined , that have the values null and undefined respectively. We mentioned these briefly in the Basic Types section. By default, the type checker considers null and undefined assignable to anything. Effectively, null and undefined are valid values of every type.

What is meant by type inference?

Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.


3 Answers

Most of today's javascript community would probably support inference motivating their choice by the fact that type inference is somehow easier to read (i.e. less letters) but ease of reading is not only less reading. Less letters is an imprecise metric for program simplicity consider:

I hp I mk m slf clr vs I hope I make myself clear

Be open try both approaches work your way towards a strong opinion. Yet be flexible and don't let your opinion to stand in your way.

Remember that

opinion is what I have when I haven't done enough research

If you understand the consequences of one decision over another you don't need an opinion you just choose a more preferable option. In this case you remove yourself from a decision-making process allowing a common sense or logic to dictate the actual shape of the code you write. It may save you at a later point in time from justifying yourself by saying something like "I'm an artist I see things this way".

This line of thinking makes it obvious why it's in most cases a good idea to support your team's decision.

It's bad idea to procrastinate and wait for error to pop in runtime as there is no reason for your program to actually die in agony by exception. It's a lot faster and cheaper to identify an error before you commit and deploy your code as it would take a lot more resources from your team for context switching in terms of creating tickets, planning them, investigating or knowledge sharing them and having them fixed. Likewise it is cheaper from business perspective to not make mistakes as each bug can be measured in loss of revenue so what's the point in even considering a gamble of check by runtime as an option? Just make sure your types are precise and extensive.

This is the reason why I personally tend to prefer explicit types. My list of pros and cons tells me that types are not underwear so no need to hide them. Static type system aligns a formal mathematical proof that your program is correct. And it's there for a reason - support your type system and it will support you in return. Don't be lazy decorate variables with types. Even when type declaration might be seemingly omitted it's still a good idea to provide a typename.

There were many situations when multibillion losses were caused to companies and projects by the lack of type system or its imperfection.

Having a type name before your eyes can help you trigger a second thought and save you from making a mistake even if your compiler isn't strict enough to check (i.e a number is not always a number that you'd might expect consider the following case:

const x: Miles = 3;
const y: Kilometers = 5;
...
const result = x + y; // Result type is obviously unknown so the operation shouldn't be implicitly allowed

If your types are becoming too big or complex to write each time it's a hint for you that it's time to do something about it.

But who knows I may be wrong, like anyone...

like image 109
Lu4 Avatar answered Nov 10 '22 10:11

Lu4


In your example it is just about style, hence, it has not impact to your code from compilation perspective. Be aware this is for the cases where the variable value explicitly defines its type, which might make your code complicated to read in cases of resigning values from other variables.

In other words it might be better you do:

name: string = "John"
bday: Date = "1980/01/10" //the compiler says there is an error

And avoid:

name = "John"
bday = "1980/01/10" //no compiling error, but it should be new Date("1980/01/10")

Note: Undefined types will always be considered as any.

like image 21
Cleriston Avatar answered Nov 10 '22 09:11

Cleriston


Declared types do not matter at all at runtime. When the Javascript is generated all types will be removed since Javascript does not support specifying variable types.

As to why TSLint prefers type inference ove explicit typing I would say it is probably to keep things DRY (don't repeat yourself). Since the compiler can do the typing for you there is no reason to add more noise to the code.

like image 26
Titian Cernicova-Dragomir Avatar answered Nov 10 '22 11:11

Titian Cernicova-Dragomir