TypeScript Price

Original author: Eric Elliott
  • Transfer
In 2017-2019, it was possible to observe a serious growth of TypeScript. It happened for obvious reasons. There is a lot of good in this language. Almost half of the 2018 State of JavaScript survey respondents have already tried TypeScript and are going to write on it in the future. TypeScript is very popular, but is it worth using it in large-scale software projects?



In this material, an attempt is made rather strictly, based on the numerical indicators and practical experience of the author, to analyze the effect of using TypeScript in the development of large projects.

About TypeScript Growth


TypeScript is one of the fastest growing languages. Currently, it is the leading language of those that are compiled into JavaScript. Here is the TypeScript data from Google Trends.


Google Trends data for 2014-2019 on the dynamics of TypeScript popularity

The following is information from GitHub, reflecting the interest of programmers to work on the development of various programming languages.


GitHub data on the growth of programming languages ​​in terms of the number of contributors

Above are very impressive figures indicating the growing popularity of TypeScript, which cannot be underestimated. But it should be noted that TS is still far from being recognized as the leading language of the JavaScript ecosystem. If you compare the JavaScript ecosystem with the ocean, then TypeScript will be a big wave in this ocean. Here is a comparison of JavaScript (red line) and TypeScript (blue line) according to Google Trends.


Google Trends data for 2014-2018 on the dynamics of the popularity of JavaScript and TypeScript

But the information from GitHub about the leading programming languages ​​used to create repositories in 2008-2018.


GitHub data on the number of repositories created using various programming languages.

You can see that, according to the number of repositories, TypeScript is not in the top five languages.

It should be noted that in 2018 there was a turning point in the history of TypeScript, and in 2019 this language will be used in a variety of real projects. If you are a JavaScript developer, then you, under such conditions, simply will not have a choice. The decision to use TypeScript in a certain project, on which you have to work, already, without taking into account your opinion, will be made. You do not need to be afraid to learn and use TypeScript.

However, if you are the one who decides which language to use in a certain project, then you need to have a realistic understanding of the strengths and weaknesses of TypeScript. When making decisions, you will need to understand whether the choice of TypeScript will have a good or bad effect on the project.

My experience suggests that TypeScript has its advantages and disadvantages, but one cannot say that its use, in general, has a positive effect on projects. TypeScript was liked by many developers, and there are many things connected with this language that I, who have tried it in practice, really like it. But you have to pay for everything.

Prehistory


I came to JavaScript from the world of statically typed languages, such as C / C ++ and Java. At first, it was hard for me to adapt to the dynamic typing used in JavaScript, but as soon as I got used to it, I felt like a person who came to the exit of a long dark tunnel and saw the light. Static typing has a lot of positive features, but the same can be said about dynamic typing.

In the past few years, I have periodically been immersed in TypeScript development. As a result, I had more than a year of TypeScript practice. I led several large teams using TypeScript as their primary language. This allowed me to evaluate the impact of TypeScript on the development of large projects and compare similar projects with similar projects that used plain JavaScript.

In 2018, it was possible to observe the risedecentralized applications. Most of these applications used smart contracts and open source solutions. When developing applications for Internet values ​​(Internet of value), errors in programs can cost users money. Now, more than ever, it is important to write reliable code. Since such projects are usually open source, I thought that what we use to develop TypeScript is good, because it will make it easier for other TypeScript commands to work with our solutions, and, at the same time, this ensures compatibility of our code with projects that use javascript.

In the process of practical use of TypeScript, I began to understand much better the advantages and disadvantages of this language. It became clear to me how the choice of TypeScript can have on a software project. I regret to say that my experience with TypeScript was not as successful as I wanted. If TypeScript is not significantly improved, then I will not choose this language for another large-scale project.

TypeScript strengths


TypeScript, in the long run, still seems to me a positive development. I want to love this language, and I still definitely like some of its features. I hope that TypeScript developers and his supporters will see constructive criticism in this material, and not baseless attacks on this language. TypeScript developers can fix some of its flaws, and if they do, I can repeat my analysis of the effectiveness of this language and come up with different results.

Static typing can be quite useful in that it helps to document functions, makes the code clearer, and reduces the cognitive overload of the programmer. For example, I usually find the Haskell type system that helps to work, does not require time and effort, is convenient, unobtrusive. But sometimes even the flexible Haskell type system and its higher-kinded type prevent it from working. For example, try typing a transducer using Haskell or TypeScript. It’s not easy to do, and the result may be a little worse than its untyped equivalent.

I like the fact that in TypeScript type annotations, if they interfere, can be optional. I like the fact that Type Typification is used in TypeScript, and the fact that there is some support for type inference (although there are many opportunities for improvement in this area).

TypeScript supports interfaces that are suitable for reuse (as opposed to built-in type declarations). Interfaces can be used in different ways for annotating APIs and function signatures. One interface can have many implementations. Interfaces are one of the best features of TypeScript, and I would like something similar to appear in regular JavaScript.

One of the strengths of TypeScript is its toolkit. For example, using a suitable editor (like Atom or Visual Studio Code), for which high-quality TS plug-ins are created, gives the developer the best JavaScript tools in the ecosystem. Developers of other plug-ins should study TS-plug-ins and think about how, using the ideas embodied in them, they can improve their development.

TypeScript performance analysis


Now I’m going to evaluate TypeScript on several indicators, putting the marks in the range from -10 to 10. This will help you better understand how good (or bad) TypeScript can have an impact on large projects.

If the score for the indicator exceeds 0, this indicates a positive impact of TypeScript on the project. If the score is less than 0, this indicates a negative impact. The value of the score of 3-5 points indicates a fairly strong impact. 2 points indicate average exposure. 1 point - relatively weak impact.

Those figures that I will continue to operate on, it is difficult to measure accurately. In my assessments I will, to some extent, be subjective. But I tried to make these assessments such that they reveal as real as possible the pros and cons of using TypeScript in real projects.

All the projects that I analyzed, grading, contained more than 50 thousand lines of code. They were the fruit of the work of several programmers for several months. One of these projects is based on Angular 2, it used TypeScript. It was compared with a similar project written using Angular 1 and plain JavaScript. All other projects are based on React and Node using TypeScript. They were compared with similar projects that used regular JavaScript. Some indicators, like bug density, were estimated only approximately. All the teams that worked on the projects consisted of experienced and novice TypeScript developers. All members of such teams had the opportunity to interact with more experienced mentors who helped them adapt in the field of TypeScript development.

The objective data that I have at the expense of a small sample size is too heterogeneous, there is too much noise in them, therefore, based on them, it is impossible to make any certain objective judgments that could be made, relying on fairly accurate figures and not risking too much make a big mistake. One JavaScript project showed a density of errors in production that was 41% less than a comparable TypeScript project. In another comparison, the TypeScript project showed a 4% lower error density than a comparable JavaScript project. In this case, it is obvious that the number of errors that reached the product release stage is much more affected not by the use of TypeScript in the project, but by the presence or absence of other measures to ensure the quality of the code. This distorts the performance to such an extent

Such a wide range of objective indicators has led to the fact that I decided not to use them, focusing on the pace of implementation of project capabilities and on observations pointing to those areas of the life cycle of projects in which the most time was spent. Below, analyzing the indicators, we will talk about this in more detail.

Since in my analysis there is a strong subjective component, you need to consider the possibility of inaccuracies in the interpretation of indicators (this is reflected in the diagram). But the general conclusions of this analysis are able to show a realistic picture of what can be expected from the use in a certain TypeScript project.


TypeScript Performance Analysis

I can already hear objections regarding the low ratings of TypeScript benefits, and, frankly, I cannot completely reject these objections. TypeScript, in fact, gives the programmer some very useful, powerful features. There can be no doubt about this.

In order to understand the reason for the appearance in my analysis of comparatively low and rare positive evaluations, one should have a good understanding of what I compare TypeScript to. This is not “just JavaScript”, but JavaScript and tools created for effective development in this language.

Consider the indicators shown in the diagram.

▍ Developer Tooling


The toolkit is my favorite TypeScript feature, which is probably the strongest practical advantage of using this language. Due to the high-quality tools, the cognitive load on the developer is reduced. It has hints on the types of interfaces, in the process, in real time, potential errors are trapped. If developing on regular JavaScript using good plugins would have nothing like this, I would give TypeScript a higher positive rating. But in our case, 0 points is something that can already be used when programming in JavaScript, that is, with which we compare TypeScript, is already at a fairly high level.

Most TypeScript advocates do not seem to understand very well what exactly TypeScript competes with. The point is that the choice of tools is not a decision on whether to use TypeScript or JavaScript without any additional tools. This is a choice between TypeScript and the entire rich ecosystem of tools for JavaScript development. The code completion and error detection tools for regular JavaScript give 80-90% of what is commonly considered TypeScript strengths. This happens, for example, when using code completion tools, type inference tools and linters. When using the type inference system and when using the default function parameters that appeared in ES6, the developer has hints that are very similar to those available when working on TypeScript code with type annotations.


An example of auto-completion of regular JS code with type inference

To be honest, if you use default parameters to provide hints on types, then you absolutely do not need to annotate TypeScript code. This is an excellent technique to reduce the number of auxiliary syntaxes, which are one of the disadvantages of TypeScript.

The tools used to write TypeScript code are perhaps a little better, they look more holistic, but all this is not enough to put TypeScript much more commendable and to override the shortcomings of this language.

▍ Documentation API (API Documentation)


Another major advantage of TypeScript is better API documentation. In fact, we can say that the API documentation always corresponds to the state of the source code. Documentation can even be generated based on TypeScript code. According to this indicator, TypeScript could also be given a higher score - if, programming in JavaScript, you could not use something like JSDoc , Tern.js and a lot of tools to generate documentation. Personally, I am not a fan of JSDoc, so TypeScript in my analysis for this indicator receives a rather high rating.

It should be noted here that even using the world's best embedded documentation in the code, one cannot do without this documentation, so it’s fair to say that the TypeScript capabilities expand the existing documentation preparation capabilities rather than replace them.

▍Type Safety (Type Safety)


When comparing the type safety TS and JS, as it turned out, it is not possible to identify a special difference. TypeScript advocates often talk about the advantages of type safety, but it cannot be said that type safety significantly reduces the density of production errors. This is an important point, since the use of code review and TDD has a very serious effect on the elimination of errors (the mere use of the TDD technique reduces errors by 40-80%). If you combine TDD with project architecture analysis, specification checking, and code review, you can get more than a 90% reduction in error density. Many of these techniques (in particular, TDD) can help in finding the same errors that can be detected by means of TypeScript, as well as many errors that TypeScript cannot detect.

Here we present some of the calculations from this study . The theoretical maximum of “publicly available” errors that can be detected by means of TypeScript is about 15%. “Publicly available” errors are those that went through the project development phase and ended up in a public repository.

In the aforementioned study, errors that were known in advance were monitored. This included knowing which lines of code were changed to correct errors, while the problem and its potential solution were known before code typing. This means that even the knowledge of the existence of errors did not allow, by means of TypeScript, to detect 85% of “publicly available” errors.

Why is TypeScript unable to detect so many errors? Why am I saying that 15% of the errors found are the theoretical maximum of TypeScript? To begin with, it is worth noting that, in accordance with the study in question, errors in specifications lead to the occurrence of approximately 78% of errors in publicly available GitHub repositories. The inability to clearly formulate program specifications or the inability to implement specifications correctly lead to the most common type of error. This automatically leads to the fact that most of the errors in TypeScript software projects cannot be detected or prevented. The authors of the study, among other things, identify and classify errors that are not detected by TypeScript. Here is a histogram with information about such errors.


Errors that are not detected by TypeScript. The

“StringError” example is an error that occurs if a string is used where a string is needed, that is, an error does not occur in types, but the contents of this string cause an error (for example, may be an invalid URL). Using static analysis tools, you can identify some of these errors by examining the contents of strings and using descriptions of this content. But this will only give the prospect of correcting a small fraction of a small percentage of errors. As a result, we are talking about the fact that TypeScript tools can hardly ever reveal more than 15-18% of errors.

It may seem that 15% is already quite a lot. Why can't TypeScript detect a significantly higher percentage of errors?

Since there are many errors that cannot be identified by means of static typing, it would be irresponsible to refuse to use other quality control methods like code review and TDD. Therefore, it is not fair to rely on TypeScript being the only tool of a project used to deal with errors. In order to realistically perceive the considered indicator of our TypeScript efficiency analysis, it is worth counting the potential number of errors detected by TypeScript, after all errors identified by other methods are excluded from their number.

Suppose your project would contain 1000 errors in the event that you did not take any measures to combat errors. After the project was properly tested, the potential number of errors capable of reaching production was reduced to 100. Now, to see the real possibilities of TypeScript, we will look at how many of these errors can be detected with its help. Since about 80% of errors using TypeScript cannot be identified, and given that, in theory, all errors detected by TypeScript can be detected by other means, such as using the TDD methodology, we, having done quite generously, assume that TypeScript will detect 8% more errors. Here we, moreover, proceed from the assumption that, according to which, about half of the errors that TypeScript reveals, we did not find in other ways.

  • The project, in which measures to combat errors do not apply, contains 1000 errors.
  • When using measures to combat non-TypeScript errors, 900 errors were detected.
  • After checking the project with TypeScript tools, 92 errors remained. This means that due to the introduction of TypeScript, 8 more errors were found.


Errors in the project without checks, errors left after the review of the code and after the application of TDD, and errors that remained after checking the project with TypeScript tools

Someone may disagree with these conclusions, saying that using the static type system does not need to write huge number of tests. But such arguments do not hold water. TypeScript does not replace other means of dealing with errors. Even if TypeScript is used in a certain project, it is still necessary to do without other measures for finding errors.


Errors detected by TypeScript and other methods

Suppose that TypeScript tools revealed 15% of the initial number of errors of the above-described hypothetical project. That is - 150 out of 1000. But even with this approach, if you do not take into account errors found by TypeScript, other means of finding errors will allow you to find 900 errors. This leads to the obviousness of the fact that, in choosing the means to deal with errors, we are not talking about choosing a TypeScript or something else. For finding errors, you can take both TypeScript and other tools, which, as shown above, will lead to the detection of 908 errors out of 1000 (recall that we reached this figure, assuming that other error finding tools reveal a lot of errors that can be detected by TypeScript).

I had to implement quality management systems in large-scale projects that cost many millions of dollars. I can say that my expectations regarding the effectiveness of such systems are in the region of 30-80% reduction in errors. Similar figures can be found in the following works:

  • Checks on project architecture and specifications can eliminate up to 80% of errors.
  • The use of TDD can reduce the number of remaining errors by 40-80% .
  • An hour spent on code review saves 33 hours of project support.

It turns out that errors associated with data types are only a small subset of the total number of possible errors, and, moreover, there are ways to look for such errors other than using TypeScript. All this allows to make an extremely clear conclusion: the use of TypeScript is not able to save the project from errors. At best, its use will only reduce their number slightly, while at the same time it will not be possible to do without other measures to combat errors. The correctness of the use of types does not guarantee the correct operation of the program.

In fact, there is a feeling that neither the developer tools nor the type safety really lived up to the TypeScript boom. But tools and type control cannot be the only TypeScript strengths, right?

▍New JavaScript features and cross-browser code compilation (New JS Features, Compile to Cross-Browser JS)


For the discussed pair of indicators, TypeScript gets a score of 0, which equates it with JavaScript. The fact is that Babel provides support for the latest JavaScript features and compiles code that uses modern constructions into code that can be executed in existing browsers.

With the following indicators, a discussion of the disadvantages of TypeScript in comparison with JavaScript begins. I do not know about you, but I feel a slight disappointment. If, when developing in pure JavaScript, you can use hints about types, auto-completion and excellent means to find errors, then we are left with the only question that is whether TypeScript strengths are those efforts that need to be made to use this language. In order to find the answer to this question, we need to take a closer look at those indicators for which TypeScript received marks with a minus sign.

▍Research of developers (Recruiting)


Approximately half of those who participated in the State of JavaScript study have already used TypeScript and plan to use it in the future, while another 33.7% of respondents want to learn TypeScript. But 5.4% tried TS and say that they will not use it again, and 13.7% say they are not interested in learning this language. All this reduces the labor supply market of TS-developers by almost 20%, which can have a serious impact on projects that need large teams of programmers. Finding employees is an expensive process that can take many months and interfere with the productive work of programmers already hired (who, more often than not, are the most qualified representatives of companies able to assess the skills of job candidates).

On the other hand, if you need to hire one or two developers, then using TypeScript can make your proposal more attractive for almost half of potential applicants. A small project can even win a little from this. If we are talking about teams of hundreds or thousands of developers, such a situation in the labor market can lead to the negative impact of the choice of TypeScript on such projects.

▍Preparation for work, initial training (Setup, Initial Training)


These activities are performed only once, so their cost is relatively low. Teams that are already familiar with JavaScript usually reach the high productivity of TypeScript development in 2-3 months, and in 6-8 months they reach a very high level of language proficiency. This, of course, is more expensive than hiring a ready-made specialist, but definitely, if all the difficulties associated with using TypeScript were limited to this, this could have been done without much thought.

▍ Missing Features


We are talking about functions of a higher order, about composition, about generics with types of higher genera and about other things like that. TypeScript is not fully compatible with idiomatic javascript. It is in this area that my main problem is revealed with TypeScript and the main source of time, effort and money spent on working with this language. The fact is that a knowledgeable JavaScript developer will often encounter situations in which it is difficult or impossible to use typing, but at the same time a diligent developer will try to do everything as it should. As a result, such a developer will spend many hours searching for suitable examples on the Internet, trying to find out how to typify what TypeScript means it is simply impossible to properly type.

The capabilities of TypeScript in this case can reduce the burden on the developer if the developer will have access to better documentation and the ability to quickly find out the current TypeScript limitations. As a result, the developer will spend less time trying to do the impossible with the use of higher-order functions, declarative composition of functions, transducers, and so on. In many cases, the correct, well-readable, supported TypeScript typing of code is simply impossible. It is necessary for developers to be oriented in such situations as quickly as possible, and, as a result, they would spend time not on finding non-existent answers to their questions, but on useful things.

▍Continuous Learning (Ongoing Mentorship)


Although developers quickly reach a good level of performance in the field of TypeScript, they need quite a lot of time for confident programming in this language. Yes, and I, for example, still think that I still need to learn a lot of things. In TypeScript, the same constructs can be typed differently. As a result, in order to understand the strengths and weaknesses of different approaches, in order to find out exactly how knowledgeable people recommend, you need much more time than learning the basics of the language.

For example, new TypeScript developers tend to overuse annotations and embedded type descriptions in code, while more experienced developers tend to reuse interfaces and create type descriptions that are separate from the rest of the code in order to get rid of syntax disorder, which is caused by the type annotations embedded in the code. More experienced developers, in addition, seek to modify types in such a way that, at compile time, to get better error messages.

Increased attention to typing constantly takes time of developers. Something similar can be observed when a new programmer is accepted into the team. But it is also expressed in the fact that experienced TypeScript developers who have discovered something useful are sharing this with the team. This “lifelong learning” is only a normal side effect of team work on a project, and it’s a healthy habit that saves money in the long run. But such things translate into costs of time and effort, and therefore into costs in monetary terms, while TypeScript only increases such costs.

▍ Additional load on programmers associated with typing (Typing Overhead)


In this indicator, I include the additional burden on programmers, which is created by the need for entity typing, as well as the need for testing, debugging, and support for type annotations. Type debugging is the type of expenditure on using TypeScript that is often ignored. Type annotations are subject to their own errors. Typification may be too strict, too free, or simply wrong.

Since I first encountered this problem, it has become much less serious. Many libraries used in software projects are now equipped with information about types, so programmers do not have to spend too much time researching such third-party libraries and creating types for them themselves. However, many of these type descriptions still work incorrectly; in many packages, with the exception of the most popular, they may be outdated.

Therefore, programmers have to tinker with third-party libraries themselves, in order to work with them they need information about types. Often, developers try to influence the fact that typing information is maintained in the libraries they use up to date, this is done in different ways and with different results.

In addition, you can notice a noticeably increasing “syntactic noise” when using TypeScript. In languages ​​like Haskell, typing is usually represented by a short one-line construct above the function being defined. In TypeScript, especially for generics, typing information often interferes with function declaration code, and, by default, is built-in constructs.

Instead of helping to improve the readability of function signatures, TypeScript typing can often degrade their readability and complicate their understanding. This is one of the reasons why experienced TypeScript developers seek to reuse structures and interfaces, and to declare types separately from function implementations. Large TypeScript projects tend to develop their own type libraries for reuse, which can be imported and applied anywhere in the project. Supporting such libraries may be an additional factor that distracts developers' time, but this is a worthwhile investment of time.

"Syntactic noise" is a problem for several reasons. The code is sought to be kept clean for the same reasons that they seek to keep the house clean.

  • If the code has a lot of auxiliary constructions, there will be more places where errors can be hidden. This means that there will be more errors in the code.
  • A large number of auxiliary constructions means that it becomes more difficult to search for what is needed in the code.

All this "syntactic noise" is similar to static in a poorly tuned radio receiver - there is more noise than a useful signal. Getting rid of “syntactic noise” is like tuning a radio receiver to the desired wave - it makes it easier to hear meaningful sounds.

"Syntactic noise" - one of the main problems TypeScript. It can be reduced in the following ways:

  • Improved generic support using higher birth types. This will get rid of some of the “noise” of the template code (in order to better understand this - take a look at the Haskell type system).
  • Support for using, by default, separate rather than inline type descriptions. If the standard in the field of TypeScript development is to strive to do without built-in type declarations, then the typing syntax will be isolated from the implementation of functions, which will facilitate both the perception of type signatures and their implementations, since they will not mix with each other and will for the attention of the programmer. This can be implemented by carefully reviewing the documentation, and this can be facilitated by the appropriate attitude of experienced TypeScript developers answering questions on Stack Overflow.

Results


I still like a lot in TypeScript, and I still hope that this language will get better. Some of the problems that were discussed here can be solved by adding new features to the language or by improving documentation.

However, we should not close our eyes to these problems, and supporters of TypeScript will behave irresponsibly if they extol the advantages of this language, without saying anything about its shortcomings.

TypeScript can and should be better at type inference, in working with higher-order functions and with generics. The TypeScript development team has tremendous opportunities for improving documentation, including tutorials, videos, and collections of tips. The same applies to TypeScript restriction lists, which can help TypeScript developers save a lot of time and can significantly reduce the additional burden on commands associated with using TypeScript.

I hope that as TypeScript grows, many of those who write in this language will go through the “honeymoon” stage and understand the true value of using TypeScript and its limitations. At the same time, the more extensive the TypeScript community is, the more intelligent people will join in solving the problems of this language.

I will definitely use TypeScript, in the state in which it is now, when developing small open source projects, mainly to make life easier for other programmers who write in TypeScript. But I will not use the current version of TypeScript in my next large-scale project. The thing is that the more the project will be - the more expensive, in all senses, will be to use TypeScript for it.

Finish on an ironic note. The TypeScript official site says that we have “JavaScript that scales”. It would be more honest to add one more word to this slogan and make it like this: “JavaScript that doesn’t scale well”.

Dear readers! Please share your TypeScript experience.


Also popular now: