DEV Community

Why you should learn TypeScript today

Omer Elbaz on June 22, 2022

1. TypeScript makes code easier to read and understand. When you use TypeScript, you can see the types of variables and functions as you...
Collapse
 
miketalbot profile image
Mike Talbot ⭐

A very well put response Luke, couldn't agree more... I find JS (plus JSDoc) easier for projects that I'll mainly work on alone or in a small team and TypeScript beneficial when many people will work on the project.

Collapse
 
peerreynders profile image
peerreynders • Edited

Strangely enough it was Vite which significantly lowered the adoption barrier for me (I don't use VS Code).

esbuild's transform is so fast and the "To hell with the TypeScript errors, lets run this code now!" approach means that I don't constantly get stalled having to explain (right now, this very moment) to TypeScript what I'm doing. It's only once I get far enough into the weeds that I switch gears and go into "type linting" mode to shore up the work already done.

I do think there are two significant milestones in TypeScript competence:

  • type consumer
  • type producer

It's fairly easy to get to the "type consumer" level and that's typically all that's required when duct-taping dependencies together to "make a thing".

Maintainers of dependencies however need to aspire to the "type producer" level and that is quite a bit more work because TypeScript has a lot of concepts that other statically typed languages simply don't need (they aren't trying to bridge the gap to a dynamically typed language where it isn't unusual (and sometimes even desirable) for types to morph at run time).

The less you rely on dependencies and the more you are crafting bespoke capabilities, the more you need to push into "type producer" territory.

The one thing I still don't like is the pressure TypeScript places on coding style. Just recently I ended up this the tight ball of code:

async function rootAndRun<T>(
  timeoutMs: number,
  factory: Factory<T>
): Promise<T> {
  let disposeFn: (() => void) | undefined;
  let timeoutId;
  try {
    return await new Promise((resolve, reject) => {
      createRoot((dispose) => {
        disposeFn = dispose;

        timeoutId = setTimeout(function timeout() {
          timeoutId = undefined;
          reject(new Error('Timed out'));
        }, timeoutMs);

        // queueMicrotask/setTimeout allows `setup` to finish
        // before exercising the reactive graph with `run`
        const run = factory(function done(data, err) {
          if (data === undefined) reject(err);
          else resolve(data);
        });
        if (typeof run === 'function') queueMicrotask(run);
      });
    });
  } finally {
    if (disposeFn) {
      disposeFn();
      disposeFn = undefined;
    }
    if (timeoutId) {
      clearTimeout(timeoutId);
      timeoutId = undefined;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The JavaScript version was neatly pulled apart into separate functions

async function rootAndRun(timeoutMs, factory) {
  let disposeFn;
  let timeoutId;
  try {
    return await new Promise(executor);
  } finally {
    if (disposeFn) {
      disposeFn();
      disposeFn = undefined;
    }
    if (timeoutId) {
      clearTimeout(timeoutId);
      timeoutId = undefined;
    }
  }

  // ---
  function executor(resolve, reject) {
    createRoot((dispose) => {
      disposeFn = dispose;
      timeoutId = setTimeout(timeout, timeoutMs);
      // queueMicrotask/setTimeout allows `setup` to finish
      // before exercising the reactive graph with `run`
      const run = factory(done);
      if (typeof run === 'function') queueMicrotask(run);
    });

    // ---
    function timeout() {
      timeoutId = undefined;
      reject(new Error('Timed out'));
    }

    function done(data, err) {
      if (err != undefined) reject(err);
      else resolve(data);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

When I started typing it, TypeScript was constantly complaining how the same T could end up being different types. It's only once I inlined the functions that TypeScript finally "got it".

So when people claim that TypeScript makes refactoring easier they simply mean that it (likely) rings the alarm bells when something doesn't quite line up after you moved some code around.

However I claim that TypeScript doesn't encourage refactoring—in the sense of authoring code that is broken down into easily digestible chunks.

TypeScript's type inference pushes you toward an "inlined" coding style (which I absolutely despise) because inlined code is easier on the type inference. If you want to break things down into sensibly named and sized chunks it penalizes you with a hefty explicit typing tax which most people aren't willing to pay—leading to heavily inlined code which the JavaScript ecosystem already has enough of.

 
peerreynders profile image
peerreynders

So my "type parameters inside closures" needs more work; figures. The Maybe makes sense, I'm constantly surprised it's not with the utility types.

I just try to keep my functions small and make them do one job and do it right which makes them far easier to test, maintain …

I'm right there with you in terms of small and focused but I'm not prescient so it's far too easy for me to fall prey to premature reuse/abstraction—OO or functional.

Thank You for the assist!

Collapse
 
apimike profile image
Mike Rozner

Type script made me a lover not a fighter

Collapse
 
jwp profile image
John Peters

I love working with TypeScript. It also taught me Javascript so now I know both.
When I build webcomponents I use raw Html and Javascript.

But when working on large applications, I use TypeScript. Intellisense is too good to ignore.

 
peerreynders profile image
peerreynders

TIL: There needs to be a comma after the type parameter for an arrow function otherwise TS thinks it's JSX.

const wait =
  (milliseconds: number) =>
  <Value,>(executor: Executor<Value>) =>
    new Promise((resolve, reject) =>
      setTimeout(executor, milliseconds, resolve, reject)
    );
Enter fullscreen mode Exit fullscreen mode

The error message I was fighting:

"Argument of type T is not assignable to parameter of type T. T could be instantiated with an arbitrary type which could be unrelated to T."

CodeSandBox

Which seems to imply:

"The caller of the function specifies the type parameter, not the implementer"


If you refer back to my TypeScript version please note that I require Promise<T>.

Your version only gives me Promise<unknown>. The moment I put Promise<T> on rootAndRun() everything lights up red. The Promise<T> based on Factory<T> was the point of making rootAndRun() generic.

For Promise<unknown> we don't need generics to begin with. CodeSandbox

unknown is extremely useful under very specific circumstances but when overused it reminds me of the Java pre-Generic Object fiasco in terms of type safety.


that could be reused

How OO of you 😁

In this case reuse isn't the goal as this is only for testing support, so not being coupled via reuse (Beware of the Share) is a good thing.

Also in general I try to stick to the Rule of Three:

  • You must have looked at at least three systems to understand what is common across them (and therefore reusable)
  • It takes three times as much effort to make something reusable as to make it usable
  • You will receive payback after the third release.

In this case the goal was to "unroll" it enough to make it more understandable.

Collapse
 
samantha_parker_3fe9f8171 profile image
Samantha Parker

A detailed search engine optimization analysis is the foundation of any effective SEO service. By understanding your website's current standing and the competitive landscape, you can develop a tailored strategy that drives long-term success.

Collapse
 
samantha_parker_3fe9f8171 profile image
Samantha Parker

One of the biggest challenges in digital services is ensuring that websites are easily discoverable by search engines. technical seo serviceTechnical SEO services address this challenge by optimizing site structure, improving load times, and ensuring proper indexing. These efforts help businesses overcome obstacles and achieve better search engine rankings.

Collapse
 
gitrog555 profile image
GitRog555 • Edited

Using a timescript is a sign of the coder's respect for other developers, it is a sign of the programmer's maturity and high level of team responsibility. For me, one source was an example of using a timescript; their authors do my programming homework with understandable hints and clarifications in the code.

Collapse
 
andrewbaisden profile image
Andrew Baisden

TypeScript made me a better JavaScript developer.

Collapse
 
dustin12 profile image
dustin

I have learned typescript in 2 years and now doing job to help students in do my course for me