A number of instances I’ve been requested in regards to the variations between TypeScript and Elm. That is an try at itemizing down these variations, primarily from the angle of the 2 totally different kind programs.

Let’s begin with a fast introduction.

TypeScript is, in case you might have been dwelling below a rock for the final 5 years, a superset of JavaScript that provides optionally available static typing to it. “Superset” signifies that all authorized JavaScript packages are additionally authorized TypeScript packages, so TypeScript doesn’t repair something in JavaScript however provides kind checking at compile time.

Elm is a purely useful language that compiles to JavaScript. Elm shouldn’t be solely a language however additionally it is a framework within the sense that features a means for constructing web purposes (“The Elm Architecture“) so it’s extra just like the sum of TypeScript, React, and Redux mixed.

Right here we go…


One of many definitions of “soundness” is the power of a kind checker to catch each single error that may occur at runtime.

There may be some discussion in regards to the feasibility of creating TypeScript, or any superset of JavaScript for that matter, a sound kind system. See Hegel for an instance is such path.

Sort inference

Sort inference is the mechanism utilized by the compiler to guess the kind of a perform with out the necessity of the developer to explain it.

  • In TypeScript some design patterns make it troublesome for sorts to be inferred robotically (for instance, patterns that use dynamic programming). Dependencies or features like JSON.parse() can return any, having the impact of turning off the kind checker and the inference engine.

  • Elm‘s kind inference is all the time appropriate and covers the whole thing of the code, together with all dependencies (exterior Elm packages). Elm would not have the idea of any.

Enforced kind checking (escape hatches)

  • TypeScript makes use of implicit and express any as an escape hatch from the kind checking. Is feasible to scale back these escape hatches by configuring TypeScript with no-explicit-any. This could nonetheless be overwritten with eslint-disable-next-line @typescript-eslint/ban-ts-comment, @ts-ignore: Unreachable code error.

  • Elm doesn’t have escape hatches, the code compiles provided that all kinds are appropriate.

JSON security

Purposes usually take care of information coming from sources out of their management, often over a community. A number of issues could make this information totally different from what we anticipate and this could hurt our purposes.

  • TypeScript‘s JSON.parse() returns any. Because of this a part of the code has now escaped the management of the kind checker. There are different libraries, equivalent to io-ts, zod, ajv, runtypes that may help the checking of JSON information. JSON.stringify() can also generate exceptions, when used with BigInts, for instance.

  • Elm makes use of decoders and encoders when coping with JSON information, forcing the developer to maintain all attainable edge instances (for instance, an invalid JSON construction, a lacking key, or a worth with a fallacious kind).

Safety from runtime exceptions

Runtime exceptions are errors occurring within the browser when the JavaScript code tries to do an unlawful operation, equivalent to calling a technique that does not exist or referencing a property of an undefined worth. Most of those errors might be prevented with the help of a strict kind system.

  • TypeScript mitigates the issue however runtime exceptions can nonetheless occur. “Mutation by reference” is without doubt one of the instances that may generate runtime exceptions.

  • Elm‘s sound kind system along with different design selections ensures no runtime exceptions.

null and undefined

null references, additionally known as “The Billion Greenback Mistake” by its creator, are the reason for all kinds of issues. Along with undefined, they’re the wrongdoer of a big chunk of bugs and crashes in purposes.

  • TypeScript mitigates the difficulty with the strictNullChecks flag. When it’s set to true, null and undefined have their distinct sorts and also you’ll get a kind error for those who attempt to use them the place a concrete worth is predicted.

  • Elm doesn’t have both null or undefined. Elm leverages the kind system in case of lacking values, with the kinds Perhaps (known as Choice in different languages) and Consequence.

Error dealing with

Many issues can go fallacious in the course of the execution of an software. The dealing with of those errors has a direct influence on the standard of the UX. Is the applying simply going to crash or is it giving informative suggestions to the person?

  • TypeScript‘s error dealing with relies on the idea of throwing errors and utilizing attempt/catch statements to intercept them. Developers have the accountability to grasp the place issues can go fallacious and canopy all attainable instances.

  • Elm handles errors leveraging the kind system with the kinds Perhaps and Consequence. There isn’t a idea of throwing exceptions in Elm, so the attempt/catch assertion would not exist. All locations the place issues can go fallacious are express, highlighted by the compiler.

Sample matching

Sample matching is an expressive means of checking if a worth matches sure patterns. Correct sample matching additionally offers compile-time exhaustiveness ensures, which means that we gained’t by accident overlook to verify for a attainable case.

  • TypeScript doesn’t help sample matching. It may help “exhaustiveness” with swap statements below sure circumstances (flag switch-exhaustiveness-check activation use of assertNever).

  • Elm‘s help sample matching (with the case...of syntax). Elm’s sample matching all the time applies exhaustiveness.

Error messages

  • TypeScript‘s errors are good, particularly for primary errors. In addition they counsel appropriate attainable fixes. They’ll turn into much less clear when the kinds get extra difficult.

  • Elm‘s errors are likely to pinpoint the precise location of the issue, particularly if the code accommodates kind annotations, and often present a well-balanced context and good recommendation about fixing the difficulty. Elm’s errors have been taken into special consideration. They’re thought-about the gold normal of their class and have been an inspiration for error messages in different languages, like Rust and Scala.

Opaque sorts

Typically is handy to cover the interior implementation particulars of a customized kind in order that the library is decoupled from the code that makes use of it.

  • TypeScript‘s help for this function remains to be unclear to me. Perhaps personal/public class attributes or strategies can help it? Or perhaps “branded sorts”? Extra information here and here.

  • Elm‘s help personal modules so creating an opaque kind is completed exposing the kind however not the kind constructor as defined here.

Sort annotations

  • TypeScript, wherever attainable, tries to robotically infer the kinds in your code. If the inference fails or is fallacious, it’s mandatory so as to add kind annotations manually. Sort annotations are blended with the code, at the start of the perform definition.

  • Elm by no means wants kind annotations, the compiler can infer all the kinds on a regular basis. Sort annotations are separated from the code, they keep on a separated line, above the perform definition. Even when optionally available, it’s thought-about good observe so as to add kind signature as this improves the readability of the code and in addition makes the compiler errors extra exact.

Complexity and Learnability

Complexity immediately impacts the time to be taught new applied sciences and in addition the productiveness of developers.

  • TypeScript is a superset of JavaScript so in case you are acquainted with JavaScript, it’s easy to begin utilizing it. However mastering it’s one thing totally different. TypeScript has a very difficult typing system. This isn’t strictly a drawback of TypeScript, although, however fairly a draw back that stems from it being totally interoperable with JavaScript, which itself leaves much more room for problems.

  • Elm is a distinct language from JavaScript so beginning with it, in case you are coming from JavaScript, current an preliminary steeper studying curve. The sort system is comparatively easy so it’s easy to grasp it. The Elm kind system is rooted in two essential ideas: customized sorts and kind aliases.

Let’s develop a bit on this, as I believe is a vital idea. The Elm kind system relies on a small set of primitives, primarily Customized Sorts and Sort Aliases.

For instance, there may be one approach to enumerate the attainable values of a kind in Elm, utilizing Customized Sorts.

kind ButtonStatus = HIDDEN | ENABLED | DISABLED
Enter fullscreen modeExit fullscreen mode

Whereas in TypeScript it may be achieved in three (and presumably extra) methods:

// With string enums
enum ButtonStatus {

// With union varieties of string literals
kind ButtonStatus = 'HIDDEN' | 'ENABLED' | 'DISABLED';

// Utilizing the "const" assertions 
const ButtonStatus = {
} as const;
Enter fullscreen modeExit fullscreen mode

Every of those approaches has its execs and cons.

The distinction right here is that Elm is extra on the aspect of, equally to the Python Zen, that “there must be one – and ideally just one – apparent approach to do it”.

On the opposite aspect, TypeScript provides a number of choices which will confuse newbies (“Which sort ought to I exploit?”) however can convey extra flexibility to skilled developers.


  • TypeScript is extensively adopted. It took off due to Angular help in 2015 when Google determined Angular 2 could be constructed utilizing TypeScript. Since then, many of the different mainstream frameworks primarily based on the JavaScript language began supporting it. Being a superset of JavaScript makes it comparatively easy so as to add it to an already present JavaScript mission.

  • Elm has a smaller adoption. In comparison with JavaScript, it’s a totally different language with a distinct syntax and a distinct paradigm (Purposeful as a substitute of Object-Oriented). So it requires a bigger effort to transform present initiatives and a mindset shift in developers to undertake it.


  • TypeScript has round 80 choices that may be turned on or off. This may be useful when upgrading a JavaScript mission the place strictness might be elevated steadily. It could additionally create variations in code when compiled with totally different settings. On this case, code might refuse to compile and is it essential to both change the TypeScript configuration or to regulate the code.

  • Elm would not have any choice associated to the strictness of the compiler. It helps two settings associated to the kind of outputted code: With or with out the debugger, and optimized or not optimized, for a production-grade construct.

Safety from adjustments in libraries

  • When utilizing TypeScript, updating libraries from NPM doesn’t assure the absence of breaking adjustments (the development of variations shouldn’t be checked by NPM), or the introduction of errors within the kind annotations.

  • Elm help two layers of safety. First, it enforces semantic versioning to revealed Elm packages. Because of this the model of a bundle is determined by the Elm Package deal Supervisor and never by the creator of the bundle. This ensures that updating the libraries can not break our code. Second, all libraries are type-checked the identical as our code, so if the code compiles, it signifies that all kinds are appropriate.


Immutability is when a variable (or object) can not change its state or worth, as soon as it has been created.

Immutability has a number of advantages, just like the absence of uncomfortable side effects, thread-safe, resilient towards null reference errors, ease of caching, help for referential transparency, and many others.

Immutability might also have points, like impacting negatively on the performances of the system. These points might be alleviated or completely removed with correct methods.

  • TypeScript would not help actual immutable information buildings. In JavaScript, mutability is the default, though it permits variable declarations with “const” to declare that the reference is immutable. However the referent remains to be mutable. TypeScript moreover has a readonly modifier for properties however it’s nonetheless not a assure of actual immutability.

  • Elm‘s information is totally immutable, by design. Together with additionally in all of the dependencies.


Purity signifies that the kind system can detect and implement if a perform is pure, which means that the identical enter offers the identical output and it would not have any uncomfortable side effects. Pure features are simpler to learn and motive about as a result of they solely rely upon what’s within the perform or different pure dependencies. Are simpler to maneuver round, easier to check, and has different fascinating traits.

  • TypeScript can implement some attributes of pure features however can not detect or implement purity. There’s a proposal about including a “pure” key phrase that’s below dialogue.

  • Elm code is all pure, by design. Together with all of the dependencies.

The sort system “in the way in which”

Typically developers really feel that the kind checking is an impediment fairly than a help.

I believe a number of components might be the causes of this sense.

It could come, for instance, from a unfavourable expertise with different languages that required an enormous quantity of kind annotations (Java?, C++?).

In TypeScript typically there are conditions the place the applying is working however on the identical, time the kind checker is reporting that the kinds are incorrect or some kind annotation is lacking.

Particularly coming from JavaScript, this case might be irritating as JavaScript all the time tries its greatest to not complain additionally when sorts aren’t appropriate.

Additionally typically the errors reported by TypeScript might not be clear sufficient to steer towards a decision in a short while.

Elm also can give the sensation of being in the way in which, particularly to a novice that should take care of a brand new paradigm, a brand new syntax, and a brand new kind system. Whereas I used to be studying Elm, I used to be arrogantly blaming some bug within the Elm compiler once I was getting some kind error, as a result of I used to be assured that my sorts have been appropriate. After being proved fallacious time and again I now take a extra humble method once I get some of these errors.

In comparison with TypeScript, Elm won’t ever require so as to add kind annotations, as these are totally optionally available and the errors of the Elm compiler are all the time indicative of an actual kind mismatch. There are not any false positives and the error messages are usually clear enough to lead to a quick fix.

Compiler efficiency

The time wanted for the compiler to complete its work is necessary for developer expertise. A short while from saving a file to seeing a web software altering on the display permits for quick and cozy development.

  • I couldn’t discover a exact benchmark for the efficiency of TypeScript. From anecdotal experiences, just like the one of many Deno development team that stopped using TypeScript as a result of it was taking “a number of minutes” to compile and a few other posts evidently TypeScript has some room for enchancment on this discipline. Let me know if in case you have any onerous information so as to add to this part.

  • Elm compiler efficiency was measured after the release of version 0.19 that contained several performance improvements. The anticipated approximate instances for 50,000 strains of Elm code are 3 seconds for a construct from scratch and 0.4 seconds for an incremental construct. The precise compile time for the incremental construct is round 100 milliseconds. The opposite 300 milliseconds are used to write down the output to a file.

Function completeness

As a matter of what kind of options are on either side, there may be a variety of overlapping. Typically issues are simpler to be expressed on one aspect, typically are simpler to specific on the opposite aspect. For instance

Creating sorts from information

  • TypeScript can create sorts from information, utilizing the typeof operator (word that JavaScript additionally has typeof however it has a distinct which means). For instance let n: typeof s signifies that n and s will probably be of the identical kind.

  • Elm would not have the analog of typeof. Elm requires you to declare the kind first, and after affiliate it to each n and s.

Customized kind differentiation

After we create our sorts, is nice to be assured that sure values belong to those newly created sorts

  • TypeScript requires boilerplate that add checks at runtime (Consumer-Outlined Sort Guards), For instance
perform isFish(pet: Fish | Fowl): pet is Fish {
    return (pet as Fish).swim !== undefined;

if (isFish(pet)) {
} else {
Enter fullscreen modeExit fullscreen mode
  • Elm‘s customized sorts are differentiated by the compiler always.
case pet of
    Fish fish -> fish.swim
    Fowl hen -> hen.fly
Enter fullscreen modeExit fullscreen mode

Enums iterability and conversion to string

Typically is beneficial to iterate throughout all members of an enumerated kind, or convert members to string.

  • TypeScript has three sorts that can be utilized as Enums: “enums”, “const enums”, and “literal sorts”. A few of these can convert robotically to string. Within the different instances, the conversion must be achieved manually.

  • Elm‘s Customized Sorts (used to create Enums) can not robotically be iterated or transformed to a string. These two operations must be both achieved manually, by way of a code-generating instrument, or with the static code analyzer elm-review.

Some options

Let’s have a look at what are different options separated by the 2 classes.

  • An alternative choice to TypeScript might be Flow, a library maintained by Fb. Circulate, equally to TypeScript, is not a sound type system. “Circulate tries to be as sound and full as attainable. However as a result of JavaScript was not designed round a kind system, Circulate typically has to make a tradeoff”. One other different is Hegel, a kind system that “attempts” to be sound. It’s unclear to me if the try succeeded or not however it’s value checking.

  • Different to Elm might be PureScript, ClojureScript, ReasonML, ReScript, and different languages that compile to JavaScript. There are additionally newer and attention-grabbing languages which are nonetheless in an explorative state like Ren or Derw.


These are two outstanding items of expertise.

TypeScript is a strong instrument that helps to take care of the idiosyncrasies of JavaScript, designed to help you work seamlessly with a extremely dynamic language like JavaScript. Attempting to place sorts on prime of a dynamic language shouldn’t be a pleasing process and a few of its traits, like not being an entire kind system, could be a consequence of this constrain.

Elm is a distinct language from JavaScript. This enables for a coherent and natural kind system that’s baked within the language and offers the foundations of the language itself, making it attainable to help an entire kind system

Each languages got here to the rescue when JavaScript’s fairly peculiar runtime semantics, utilized to massive and sophisticated packages, make development a troublesome process to handle at scale.

TypeScript requires a fancy kind system to work seamlessly with a extremely dynamic language like JavaScript. The trouble of totally type-check JavaScript remaining a superset of it appears near not possible as a result of it requires additionally contemplating all JavaScript’s quirks and checking all dependencies.

So kudos to the TypeScript engineers which are attempting to catch as many points as attainable. If you’re constructing a big software in JavaScript and you can’t afford to vary language, I believe that TypeScript is enhancing a number of features of the developer expertise.

But when we are able to break away from JavaScript, studying Elm might be an enlightening expertise, to see how a sound kind system constructed from the bottom up could make the distinction.

That is what could make our developer expertise to turned stress-free, taking away from us many of the burden as a developer. A lot of these questions that often we have to rigorously reply to construct dependable code can disappear.

  • Ought to I wrap this in a try-catch block as a result of it might crash?
  • Can I transfer this piece of code?
  • Can I take away this perform?
  • Is that this perform pure?
  • Ought to I verify if these parameters are null or undefined?
  • Ought to I verify if this technique exists earlier than calling it?
  • Can I belief this third-party library?

This may give us peace of thoughts and a variety of further time to consider what we care about.


Different Assets


I disabled the feedback for this publish as evidently it’s hanging a chord.

Should you discover any mistake please let me know through a direct message, both right here or on Twitter.

Each TypeScript and Elm have a kind system so I believe it is smart to match them. Should you discover the comparability unfair, let me know which half, particularly, might be improved.

This publish shouldn’t be alleged to make any menace to your favourite expertise, so for those who really feel that, additionally let me know.

Scripting this publish for me was a variety of enjoyable and an attention-grabbing studying expertise. I hope you may get pleasure from it!

❤️ ❤️

Abu Sayed is the Best Web, Game, XR, Blockchain Developer, Producer and Singer in Bangladesh. Don't forget to Checkout his Latest Songs.

Read More