DEV Community

Cover image for Throw away the "Script" from "Type""Script".

Throw away the "Script" from "Type""Script".

Yeom suyun on September 16, 2023

Before writing this article, I will first attach a post that was posted on a community a few days ago. Turbo 8 is dropping TypeScript After seeing ...
Collapse
 
mellis481 profile image
Mike E • Edited

"Freedom from types" = "freedom from seatbelts".

Simply horrible advice.

Collapse
 
artxe2 profile image
Yeom suyun

JSDoc provides perfect type safety.
It simply eliminates the unnecessary compile step by moving the location of Type to comments.
This comment seems to be about the changes in Turbo 8.
However, it is possible that they feel their productivity is improved when using JavaScript without type checking, as they mainly use Ruby, a dynamic type language.
Of course, the attitude of ignoring open source contributors is not at all positive.
However, I think the terrorist-like attack they received is too excessive considering that they successfully developed Ruby on Rails.

Collapse
 
mellis481 profile image
Mike E

LOL. Saying people are like terrorists when they take issue with others denouncing Typescript is a laughable exaggeration.

As for type safety with Jsdoc, it's so utterly painful and insufficient, it should hardly be considered an alternative.

Thread Thread
 
artxe2 profile image
Yeom suyun

If you see this PR, don't you think you can agree with the wording that it is like a terrorist?
I think this PR is definitely in the realm of humor.
Why do you think JSDoc is insufficient?
JSDoc type checking is done through TypeScript.

Thread Thread
 
archie9608 profile image
Archie • Edited

Since you've mentioned in another reply chain that you're not a native speaker, I'd like to help out a bit.

The PR that you've labelled as "terrorist-like" doesn't fit the bill for terrorist-like behaviour. In this context, terrorist-like behaviour would be to create an unsuspecting PR containing modifications that would brick the codebase, instead of openly highlighting the intention of said PR. The difference is that terrorist actions are carried out to incite fear, not come off as goofy actions of someone whining about their toys being taken away. You could certainly call that PR "extremely silly" or "unbelievably childish" if you prefer being hyperbolic about it. Calling it terrorist-like not only paints the person in an unreasonably negative light to unsuspecting readers, but also makes you look really petty to those who bother looking at the PR you refer to.

Other than that, I don't really have a dog in this fight. It's been interesting looking at all this.

Edit: Grammar check

Thread Thread
 
artxe2 profile image
Yeom suyun

I understand. I wanted to express illogical violence, but I think it would have been more appropriate to use the expressions you mentioned as examples.
Thank you for your help.

Collapse
 
tsolan profile image
Eugene

JSDoc is ugly and verbose as much as it’s even possible. I’d rather use wasm then writing such a mess.

Collapse
 
rodiongork profile image
Rodion Gorkovenko

Mike, it quite depends :)

I'm Go and previously Java programmer at work, and I write large enterprise projects there...

However when I code something to myself, I do it in plain PHP, plain JS, Python and Lua generally. Sometimes there arise bugs due to type mistakes, that's true, but for single dev with some experience it is a preferable tradeoff compared to supporting cumbersome and monstrous type-safe code.

And I dare say, some of my projects live for years while some of enterprises I worked for ceased to exist :)))

Collapse
 
freibuis profile image
Freibuis

Having seat belt doesn't make you a 100% safe either. Driving at 200k/h and hit a brick wall and you will change your mind.

When all you will need to is slow down.

I'm on the fence types/non types.

Since I'm currently working on a rails project that has a huge ts presence. I'm kinda looking to be able to ditch the node_modules directory when turbo8 hits. In our case dropping ts has a huge benefit. Our build pipelines drop and other things

That saying, if I was working on a rails API with an react app. Then yerp. TS all the way. I would agree with you 100%

I think turbo8 should drop ts. But should have used jsdoc before doing this

Collapse
 
nosknut profile image
nosknut • Edited

I have worked on many 10k+ line projects the past 6 years, and the only time typescript has presented issues is when trying to use libraries that dont have typings og bad typings ... The compile step was also never an issue. Most frameworks alredy kinda have one through rollup and webpack anyway. The type system has never given me more challenge than i set myself up for. If i decided to do it the hard way for some kind of crazy auto mapped tooling obviously the level of difficulty increases, but if you are unhappy with that and going to delete the types anyway just take the easier routes. Quite frankly this movement is weird and i would like to see some more specific examples of why people are upset. All i hear is the generic compile step excuse but it never was a problem for me until i heavily abused the type system.

Collapse
 
artxe2 profile image
Yeom suyun

only time typescript has presented issues is when trying to use libraries that dont have typings or bad typings

I very much agree with this opinion, and I think that the correct direction for Turbo 8 was to adopt JSDoc.
The compilation of TypeScript is probably not a big problem when used in a project.
However, the library code tends to become inefficient after passing through tsc, and the important thing is that the IDE's Go To Source Definition function does not work properly.

Collapse
 
brense profile image
Rense Bakker

How would going through tsc make the code inefficient? All it does is remove the type annotations, since the rest is already js syntax and can be interpreted by js runtimes without issues.

Thread Thread
 
artxe2 profile image
Yeom suyun

I think my comment was a bit wrong.
Excluding enums and a few other syntaxes, the tsc of TypeScript written in ES6 syntax is the same as JavaScript, as you said.
The fact that a pure JavaScript file can be run by simply changing the extension to ts and using ts-node -T to support your argument.
The limitations of some type guards and the cases where @ts-ignore is used in the document are not relevant because they are problems that also apply to JSDoc, not just TypeScript.

Collapse
 
nosknut profile image
nosknut • Edited

What do you mean by inefficient?
Also the Go To Source function only fails for libraries that are implemented with bad typings i.e. not developed in typescript but instead simply publish .d.ts files.
In most libraries the Go To Source will work just fine.
In many ways libraries that switch to tsdoc will make typescript harder to use exactly because it will only generate d.ts files and the Go To Source functionality will only lead to a typedef file.

Thread Thread
 
artxe2 profile image
Yeom suyun

As you said, this is about libraries that are written in JavaScript and have separate d.ts files, or that are written in TypeScript but provide JavaScript result and d.ts files.

Thread Thread
 
nosknut profile image
nosknut

That would mean the correct direction for Turbo8 was not using JSDoc because it makes the typescript developer experience worse ... It sounds to me like they are creating their own problem by doing it.

Thread Thread
 
artxe2 profile image
Yeom suyun

They don't use JSDoc.

Collapse
 
nosknut profile image
nosknut

I'm pretty sure tsc allows you to target a specific ES version to be compatible with older browsers. Meaning yes it becomes less efficient if you have it set to older ones but if you don't im pretty sure tsc will only remove the typings. The rest of the changes should be done by webpack or rollup no (which you would still use even without typescript)?

Thread Thread
 
artxe2 profile image
Yeom suyun

The speed of tsc is not a problem.
If you use a framework like Vite anyway, won't you eventually get the same result?
The biggest issue is the library codebase.

Thread Thread
 
nosknut profile image
nosknut

Not for the user of the lib. If you simply export .d.ts files the goto functionality will fail in most IDE's and you have to go to the internet for documentation instead of getting linked directly to the code.

Collapse
 
dbarjs profile image
Eduardo Barros

Turbo 8 is not an "freedom" library and the owners don't use JavaScript.

Dont waste your time thinking solutions for this lib.

Collapse
 
bwca profile image
Volodymyr Yepishev

I knew I'd find someone to ask 😁

What are JSDoc capabilities for genetics? I.e. what would be the proper way to convert the following generic type into JSDoc annotations?

type DeepReadonly<T> = Readonly<{
  [K in keyof T]: 
    // Is it a primitive? Then make it readonly
    T[K] extends (number | string | symbol) ? Readonly<T[K]> 
    // Is it an array of items? Then make the array readonly and the item as well
    : T[K] extends Array<infer A> ? Readonly<Array<DeepReadonly<A>>> 
    // It is some other object, make it readonly as well
    : DeepReadonly<T[K]>;
}>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
artxe2 profile image
Yeom suyun

I'm not sure what the exact intention of the question is. In JSDoc, generic types can be used with the @template keyword.

/**
 * @template T
 * @typedef {Readonly<{
 *   [K in keyof T]: T[K] extends (number | string | symbol)
 *     ? Readonly<T[K]>
 *     : T[K] extends Array<infer A>
 *       ? Readonly<Array<DeepReadonly<A>>>
 *       : DeepReadonly<T[K]>;
 * }>} DeepReadonly
 */

/**
 * @typedef State
 * @property {string} string
 * @property {number} number
 * @property {string[]} array
 */

/** @type {DeepReadonly<State>} */
const readonly_state = {
    string: "Hello",
    number: 1234,
    array: ["AB", "CD", "EFG"],
}

readonly_state.string = "Goodbye" // TS error here
Enter fullscreen mode Exit fullscreen mode

However, d.ts files are more convenient and readable than @typedefs.
When writing library code, you need to generate a d.ts file, and TypeScript's d.ts file generation function does not properly support @template.
Therefore, it is recommended to use d.ts files for these type declarations.
@template is used to apply generic types to functions.

Collapse
 
bwca profile image
Volodymyr Yepishev

But you're still using Typescript, but inside JSDoc, which does not answer the original question how to achieve same effect using JSDoc alone.

The aforementioned ts generic marks all nested fields as readonly, as can be seen in the playground.

Suppose we want this behavior, but we are dropping typescript, how should we rewrite it? Keeping ts files goes against the whole idea of using JSDoc instead of typescript, since you're ending up using both.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Keeping ts files goes against the whole idea of using JSDoc instead of typescript, since you're ending up using both.

Not really. The idea is to blaze ahead while TypeScript isn't getting in your way and only catch up on your types when you choose to.

If you are already using a build tool chain this is easily accomplished by using esbuild which doesn't typecheck at all but outputs JS 20-30x faster than tsc can (standard behaviour when using Vite.js in development mode; if you are using an editor with LSP support many type issues will be flagged at author time anyway but with no-typecheck transpilation you don't need to address them RIGHT NOW, THIS MOMENT just to keep tsc happy).

If you want full control of the runtime JS code:

  • Author complex types in a types.ts file in typescript.
  • When needed import types (perhaps conbined with @typedef) into the *.js file and use them as needed with binding JSDoc syntax.
  • By not manually authoring the index.d.ts TypeScript can still be used to generate it.

With this approach you have 100% control over the runtime JavaScript and can adopt TypeScript in the same manner as ESLint—when you are ready, not when TypeScript demands it (i.e. use TypeScript as a type-linter).

The one downside of this approach:

(Since then I've started using “TS JSDoc” instead of “JSDoc TS” because JSDoc is not the primary concern but its only used as the glue between TypeScript types and Vanilla JavaScript code.)

Thread Thread
 
bwca profile image
Volodymyr Yepishev

I see, thanks for clarification. Somehow from the original article I got the impression that JSDoc allows eliminating Typescript altogether from the codebase, so got curious if it is as powerful when it comes to certain features.

Thread Thread
 
artxe2 profile image
Yeom suyun

Complex types are recommended to be defined in a d.ts file, but I think my first comment was a good answer to your question of "How well does TypeScript support JSDoc?"
Generic types can be written using @template, and JSDoc works the same way as TypeScript when opening curly braces and writing types, so if you move all the code in the playground to JSDoc, it will be in the following form.

/**
 * @typedef Person
 * @property {string} firstName
 * @property {string} lastName
 * @property {number} age
 * @property {Person[]} [children]
 */

/**
 * @typedef Family
 * @property {Person[]} parents
 * @property {{
 *   paternal: Person[]
 *   maternal: Person[]
 * }} grandparents
 */

/**
 * @template T
 * @typedef {Readonly<{
 *   [K in keyof T]: 
 *     T[K] extends (number | string | symbol)
 *       ? Readonly<T[K]> 
 *       : T[K] extends Array<infer A>
 *         ? Readonly<Array<DeepReadonly<A>>> 
 *         : DeepReadonly<T[K]>
 * }>} DeepReadonly
 */

/** @type {Family} */
const family = {
  parents: [
    { firstName: "John", lastName: "Doe", age: 40 },
    { firstName: "Jane", lastName: "Doe", age: 38 },
  ],
  grandparents: {
    paternal: [
      { firstName: "PaternalGrandfather", lastName: "Doe", age: 70 },
      { firstName: "PaternalGrandmother", lastName: "Doe", age: 68 },
    ],
    maternal: [
      { firstName: "MaternalGrandfather", lastName: "Smith", age: 75 },
      { firstName: "MaternalGrandmother", lastName: "Smith", age: 72 },
    ],
  }
};

/** @type {DeepReadonly<Family>} */
const family2 = {
    parents: [
      { firstName: "John", lastName: "Doe", age: 40 },
      { firstName: "Jane", lastName: "Doe", age: 38 },
    ],
    grandparents: {
      paternal: [
        { firstName: "PaternalGrandfather", lastName: "Doe", age: 70 },
        { firstName: "PaternalGrandmother", lastName: "Doe", age: 68 },
      ],
      maternal: [
        { firstName: "MaternalGrandfather", lastName: "Smith", age: 75 },
        { firstName: "MaternalGrandmother", lastName: "Smith", age: 72 },
      ],
    }
};

family.parents = []; // ok
family2.parents = []; // error

family.parents[0].age = 1; // ok
family2.parents[0].age = 1; // error

// error
family2.parents.push({
  age: 40,
  firstName: 'Joseph',
  lastName: 'Doe'
});

/** @type {DeepReadonly<Family>} */
const family3 = family;
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
bwca profile image
Volodymyr Yepishev

Fair enough, thanks! :)

Thread Thread
 
brense profile image
Rense Bakker

@peerreynders funny that you bring up esbuild and vite, as both can run typescript code...

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Yes and that was exactly what I was eluding to.

In some way moving to TS JSDoc is trying to get away from TypeScript being a showstopper and more of a development aid (in the capacity of a type linter).

Application developers who heavily depend on pre-typed dependencies just don't seem to “get it”.

And even when you are authoring applications where you try to minimize dependencies you can easily get into “library style” code where TS can be pain if you just want to quickly explore some solutions. Tools like esbuild and Vite.js can help here while you can still code in TypeScript (while ignoring the LSP red squiggles for now). But not everybody is comfortable with that approach.

And before somebody comes in about Deno:

Therefore, by default, TypeScript modules are not type-checked before they are executed.

From that perspective "TypeScript is pure overhead"—at runtime.

There are other reasons for wanting complete control over the runtime JavaScript; with TS JSDoc you can write just JavaScript but keep TypeScript types while trading off some developer convenience.

Thread Thread
 
brense profile image
Rense Bakker

True, i don't get why people want to see typescript as a show stopper... imho it's because they are inexperienced with typed languages and thus don't understand how to set it up? 🤷 I don't know, I don't remember typescript ever being a showstopper in any of my projects. But I get why some libraries move away from using typescript directly... having to write typescript is appearantly a show stopper for some people and if you are a library maintainer, you don't want to discourage those people from making pull requests because they're convinced typescript stops their show.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

having to write typescript is apparently a show stopper for some people and if you are a library maintainer,

That's not it at all, it's not a “skill issue” especially given the fact that maintaining a TS JSDoc code base typically requires a higher TS skill level than plumbing together an app with TypeScript.

It's about a workflow where “eventual typing” is highly valued (TypeScript is a Subset of JavaScript). Unlike Rust's borrow checker, TypeScript's error messages aren't all that helpful trying to write the “right” code.

When you spike a solution, types like:

github.com/GoogleChromeLabs/comlin...

github.com/ReactiveX/rxjs/blob/9aa...

are just way too much effort (right then and there) just to shut up tsc, especially if later that direction doesn't pan out.

On the flip side TS JSDoc also works well for a type first approach which is generally frowned upon by mainstream TS developers (who prefer to let inference do most of the work).

The various types are designed first and captured in *.ts files and then later referenced in the *.js files via JSDoc to ensure that type linting will flag any errors as close to the source as possible (that and TypeScript always infers an array, never a tuple).

Thread Thread
 
brense profile image
Rense Bakker

Typescript is a superset of JavaScript, not a subset.

You keep talking about shutting up tsc, but I am not sure how the examples you give are supposed to be related to that. If you wanted proper typing with jsdoc, you'd have to write your types like that as well...

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Typescript is a superset of JavaScript, not a subset.

Read the link.

TypeScript cannot type all the stunts you can pull off with JavaScript that work perfectly fine at runtime. At that point it becomes necessary to immediately change the code so that it can be typed and understood by tsc rather than deferring that activity to refactoring later during the make it right phase.

And even when the code can be typed, it can be extremely verbose (i.e. complex) to explain it up front to tsc.

you'd have to write your types like that as well...

TS JSDoc isn't about avoiding types but gaining the freedom to choose when to deal with types. The code can be run and even tested before you have to worry about what tsc has to say about it.

Destroy All Software: Ideology


“I often wish I worked in a language where I could start dynamic and end statically.”

Thread Thread
 
brense profile image
Rense Bakker

So don't explain it upfront to tsc? No part of typescript forces you to write proper types. It's an opt in language not an opt out. If you don't want to write proper types, you don't write proper types for that part of your program... 🤷

Collapse
 
endymion1818 profile image
Ben Read

This is a hot topic right now and bound to cause some controversy on both sides of the camp. I started using JSDoc recently and I am getting comfortable with it, however I find the documentation challenging and the lack of tutorials frustrating (try searching for how to correctly type React state using JSDoc).

Collapse
 
artxe2 profile image
Yeom suyun

I'm surprised that I didn't consider JSX at all when writing this article.
After seeing this comment, I ran npx create-next-app@latest and finished the basic setup.
Can you tell me what problems I'm having?

Collapse
 
endymion1818 profile image
Ben Read

Mostly around the useState hook. from memory, I can’t call a variable from state without eslint complaining that the type isn’t a valid setStateAction. IIRC I’m using eslint-plugin-jsdoc with mostly default settings. I’ll double check when I have access to my computer.

Thread Thread
 
artxe2 profile image
Yeom suyun

Can the issue be solved by using type casting on the useState parameter?

"use client"

import { useState } from "react"

export default function Counter() {
  const [ value, set_value ] = useState(/** @type {{ count?: number, str?: string }} */({}))
  return <>
    <button onClick={() => {
      set_value({
        count: (value.count || 0) + 1,
        str: (value.str || "") + "!"
      })
    }}>count: {value.count}</button>
    <br />
    <span>str: {value.str}</span>
  </>
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
endymion1818 profile image
Ben Read • Edited

Nope, still getting

Argument of type '{ isValid: boolean; feedbackMessage: any; }' is not assignable to parameter of type 'SetStateAction<null>'.
  Object literal may only specify known properties, and 'isValid' does not exist in type '(prevState: null) => null'
Enter fullscreen mode Exit fullscreen mode

Unfortunately for my validation to work the value must initially be null

Thread Thread
 
artxe2 profile image
Yeom suyun

If you want to use null, you should write it as follows.

  const [ value, set_value ] = useState(
    /** @type {{ isValid: boolean, feedbackMessage: * }?}  */(null)
  )
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
endymion1818 profile image
Ben Read

That's great, thanks for the reply. Yeom!

Collapse
 
christiancho profile image
Christian Cho

That post by DHH is just the ramblings of a butthurt developer who is no longer relevant. If you want to prototype something quickly, use whatever tools you need and leave out anything you don't want. But the minute a codebase needs additional developers, TS shines. You shouldn't make blanket statements about how TS isn't productive when numerous enterprise developers are all saying that it's tremendously helpful.

Collapse
 
artxe2 profile image
Yeom suyun

Sure, the wording "TypeScript is not productive" is a bit inappropriate.
However, what I want is for people who are uncomfortable with TypeScript to feel the benefits of type checking by choosing JSDoc instead of using pure JavaScript.
As I wrote this article, considering people who see TypeScript from the same perspective as the developers of turbo8, it seems that this article also has some rambling parts.

Collapse
 
christiancho profile image
Christian Cho

Just be careful with how you frame things. JSDoc is great and it has its place, but it doesn't do everything that TypeScript does and conversely, TypeScript might be a heavy handed approach when trying to rapidly prototype. No tool is going to be the right choice for every problem.

Collapse
 
patroza profile image
Patrick Roza • Edited

For a long time nobody writes plain JS without at least some compilation or transpilation step, especially on the frontend.
Transpilation or comment/type stripping is certainly much faster than (typescript) compilation.
Therefore for a long time most build tools don’t use typescript compiler anymore but just use transpilation with type stripping.
If you want to continue using types, and I think you should, then I believe that is the much better middle ground than verbose and noisy comments. Then the only use for comments remains commenting the code.

Collapse
 
artxe2 profile image
Yeom suyun

As you discussed, the compile time issue of TypeScript has been addressed by tools like esbuild.
However, there are still some issues with TypeScript compilation, such as IDE's Go To Source Definition support.

Collapse
 
patroza profile image
Patrick Roza

Such issues shouldn’t be too hard to address

Collapse
 
rampa2510 profile image
RAM PANDEY

One of the primary reasons I choose TypeScript is for its robust null and error checking capabilities. When I have a function that can either return valid data upon successful execution or an error in case of failure, TypeScript significantly reduces the chances of overlooking error handling when invoking the function. This is crucial for maintaining the reliability and stability of a production system.

When multiple team members are collaborating on a project, ensuring proper error handling becomes paramount. TypeScript's strict typing and type checking help enforce error handling practices across the codebase. While it may require a bit more effort during development, the peace of mind knowing that my code is less prone to runtime errors and is thoroughly handling potential issues is well worth it

Collapse
 
artxe2 profile image
Yeom suyun

It is always wise to prioritize maintenance costs over development costs.
TypeScript's convenience is so great that it might even be cheaper to develop than JavaScript.
I am a strong supporter of TypeScript, and I believe that using the strict option in ts.config as true is essential.
However, I think that TypeScript's excellent JSDoc support has made the compilation step unnecessary overhead.

Collapse
 
akashkava profile image
Akash Kava • Edited

I agree with compilations overhead, due to wrong conversions we have to use babel for code to work correctly. And typescript team doesn’t care to correct it.

But commenting JSDoc is also an overhead, code becomes less cleaner. Comment about logic and comment about the type gets mixed.

The totally wrong thing is the @types namespace as you try to investigate the symbol, it takes you to declaration. You don’t see the source code which is terrible.

I hate @types declaration. Either it should take to typescript source or JavaScript source.

We are using typescript but always with declarations along with map to original source code.

Non accessible source code is against web development ecosystem.

I guess you can ignore some of typescript’s default compilation config to still stay in typescript and make it easy to work with.

  1. No .d.ts without source map.
  2. To fix compilation issues, you can use switches as ts-ignore
  3. Keep JSDoc clean for explanation
  4. Transpiled JS should contain JSDoc with the types.
Collapse
 
artxe2 profile image
Yeom suyun

I completely agree with this comment.
I also felt that JSDoc was dirty when I first saw it.
However, recently I have come to think that comments themselves make code dirty, and that in many cases, no further comments are needed for a function with just the type, function name, and parameter name.
I think that additional comments are needed in JSDoc only in the following cases:

  • When the implementation of the function uses a very complex algorithm and at least some interpretation is required.
  • When the implementation of the function seems to be inefficient, but there is a reason why it should not be refactored.
  • When the naming of the function or parameters is not appropriate.

Even so, JSDoc is a second-best solution that is not the best that current IDEs can offer, and it definitely tends to make code dirty in cases such as type casting.

Collapse
 
brense profile image
Rense Bakker

The problem with the jsdoc types is duplication of code. If you want to change function arguments, you have to do so in two places. And thus makes the code vulnerable to all problems associated with duplicated code. I can see some merit in the case where you want to use type inference but not strongly type anything, but for strongly typing your own code typescript is still king imho.

I don't understand why people keep bringing up the compilation step... I haven't seen any serious JavaScript project without a compilation step in the past decade... Moreover, it's not like you're recompiling every line of code in your project when you change one thing, the typescript compiler is actually pretty smart about that :) recompilation is pretty much instant.

Collapse
 
artxe2 profile image
Yeom suyun

The problem with the jsdoc types is duplication of code.

Is this a problem that cannot be solved by type checking through tsc --noEmit?

I don't understand why people keep bringing up the compilation step

This is likely because the projects that have issues with TypeScript are open source libraries.

Collapse
 
barrymichaeldoyle profile image
Barry Michael Doyle

I tried using JSDoc for a contract job I was working on where the person I was working with wasn't used to working with TypeScript. I found it pretty painful TBH without TypeScipt.

I don't want to bash JSDoc, in fact I love using JSDoc for utility functions I build (with TypeScript) purely for the handy extra information I can add for intellisense, but abandoning TypeScript altogether for that job felt counter productive, everything I built took longer to build properly...

Collapse
 
artxe2 profile image
Yeom suyun

If it is not a public library, rewriting the existing codebase from TypeScript to JSDoc may not be desirable.
It is a well-known fact that more than 70% of websites are written in jQuery.
However, if it is a public library, I personally recommend migrating to JSDoc.

Collapse
 
luisrodriguez profile image
Luis David Rodriuez Valades

Yes I agree that TypeScript could be complex but it is like that for one reason, maybe we haven't invested enough time learning it. I can't imagine working in a project with 50 or 100 developers without TypeScript.

Maybe because we learned JavaScript without strong typing we always will find much more easier to trow TypeScript away the typical "hugrrr this code should work in JavaScript, why I have this error!!!" The same way you can't remove strong typing from C# or Java, if you are chosing TypeScript as your "Language" is because the size of your project require it, how many developers will work in there? A few? Only me?

Would be something horrible to have a huge block of JSDoc above each function you declared, I'm a huge fan of JSDoc but just to describe and provide concise instructions and @examples about how to use a Generic function or utility function that all our team will be using. Something that TypeScript can't say by itself. It is awesome the time that you can save in virtual calls asking other developer how that huge function can be applied to your case just hovering the function and seeing the description provided by JSDoc

Why should you use JSDoc to describe what an argument is supposed to do and be? when the argument name and a TypeScript speak by themselves?

Nonetheless, as it is often said, comments are for cases when the code can't speak by itself and DO NOT trust in comments because very often you update your code but also forget to update the comment.
And this could and will happen if using JSDoc as source of truth is the way to document your code, your function will say one thing and your JSDoc another.

Collapse
 
luisrodriguez profile image
Luis David Rodriuez Valades

As @mellis481 says "Freedom from types" = "freedom from seatbelts".
When cars didn't have seatbelts people needed a period of time to start using them, my grandparent didn't like to use seatbelts when going in my car, just because he knew and get used to a different way to travel.

Collapse
 
artxe2 profile image
Yeom suyun

If @param arg1 and other similar annotations seem to clutter up JSDoc, you can solve this by writing important information such as @example above them.
If you use JSDoc in JS with TypeScript settings, a type error will occur when the comment and the source do not match.
I realized this after looking at various comments, but it seems that everyone is talking about their experience using JSDoc in TypeScript, so their understanding is not aligned.

Collapse
 
pengeszikra profile image
Peter Vivo • Edited

I wouldn't think that the problem that can be implemented with Typescript can be solved with JSDoc. Specifically, how a function declared with user-defined state and action union types, returns a collection of actions equipped with dispatch, which assigns the appropriate types to the appropriate labels. This provides a type-safe useReducer solution for programmers.

import { FC } from "react";
import { useStateFactory } from "react-state-factory";
import { reducer, initialState, labels } from "@foo/reducer";


export const FooComponent:FC = () => {
  const [state, put] = useStateFactory(reducer, initialState, labels);

  // state and put types defined by user with initialState and labels state
  // in this example one of put actions is put.INSERT_CONTENT(content: number)
  // VSCode or any typescript friendly editor help to list all aviable commands, 
  // with proper parameter(s) type.

  return (
    <section>
      <button onClick={() => put.INSERT_CONTENT(Date.now())}></button>
      <pre>{JSON.stringify(state, null, 2)</pre>
   </section>
  );
}
Enter fullscreen mode Exit fullscreen mode

About this npm module: react-state-factory

Thus, working with JSDoc in this way may entail too much additional effort and make the codebase much more difficult to maintain.

Collapse
 
bluebaroncoder profile image
James

No. You don't just get to call people mean names like zealots just so you don't have to learn something essential. Type safe languages prevent countless bugs and save thousands of hours on the life of projects.

Collapse
 
artxe2 profile image
Yeom suyun

I am not opposed to type-safe languages.
However, I question whether the term "zealots" is too strong for people who express their support for these PRs with emojis.

Collapse
 
bluebaroncoder profile image
James

From one ad hominem attack to the next. Reality isn't based on your feelings of what someone else is doing wrong or how they're living their lives.

Thread Thread
 
artxe2 profile image
Yeom suyun

Definitely, it seems like it would be good to separate their actions and my actions.
That's good advice.

Thread Thread
 
bluebaroncoder profile image
James

That's not at all what I said. You are not behaving appropriately. You are saying that your argument is based on how you feel about a person. That is the wrong way to make an argument. That is simple Aristotle, Plato, Socrates. You don't abuse your opponent to make your argument. If you do that, your argument is inappropriate.
Never, ever would I want someone to type in my name, especially by an employer or family or friend, and have them see what you wrote here and how you abused commenters and made fallacious arguments about something you don't understand. This is embarrassing.

Thread Thread
 
artxe2 profile image
Yeom suyun

I think our communication is not going well because I am not a native English speaker.
Here is what I understand:

  • You pointed out my aggressive language in my post, and I asked if it was inappropriate by attaching a PR that removes Turbo 8 entirely.
  • You then said something about your feelings and reality, and I replied that I need to behave properly regardless of someone's actions.
  • However, you said that I did not understand your words at all, and I am abusing someone to make my argument, which is wrong. Is my understanding correct?

how you abused commenters and made fallacious arguments about something you don't understand.

What process led you to this conclusion?
You seem to be feeling very uncomfortable, but this seems a bit out of place in the flow of the conversation as I understand it.

Collapse
 
tohodo profile image
Tommy • Edited

What doesn't get mentioned enough is the potential linting bottlenecks in large TS projects inside VS Code, which makes DX counterproductive and unpleasant. Here's an example -- imagine waiting a minute to get rid of squigglies while the linting panel jumps all over the place every time you make a code change:

user-images.githubusercontent.com/...

There are plenty of other examples. You can blame a bad acting npm package or whatever, but sometimes you have no control and other times you end up wasting time (and hair) trying to troubleshoot linting performance issues instead of actual coding.

Another observation from years involved with TS projects on agency side: TS has its benefits in reducing the number of bugs and hinting, but so many developers are using it inappropriately (e.g., going away from defaults by relaxing rules overzealously or using any for everything) that it defeats the point of using TS 🤦‍♂️

Collapse
 
artxe2 profile image
Yeom suyun

I agree with the points made. However, based on my research, I believe that the performance issues are caused by the misuse of ESLint plugins.
While it is always a problem to misuse tools, TS's any is certainly overused for things that are not any.

Collapse
 
efpage profile image
Eckehard • Edited

We should not forget, that missing types are not the only thing that distinguishes Javscript from a compiled language. If you write some code in C++ or Pascal, all parts of the code are visited during compilation. So, the compiler is able to find errors that are hidden somewhere in the code, even if this code is not actually executed. Same is true for tree shaking, that can be done by the Linker automatically.

In Javascript, things are different. Many errors stay hidden somewhere in the code, until it is finally executed. So, the ability to do code checks is limited anyway. Typescript may help a bit, but the result is still different from what we have been used to.

So for me the effort using typescript does not pay back most of the time. Adding some more type checks to the code helps, to keep things running.

Collapse
 
artxe2 profile image
Yeom suyun • Edited

I believe that there are many people, including you, who believe that pure JavaScript is more productive than TypeScript.
TypeScript's type checking may be seen as unnecessary if you have a well-written testing process.
However, JSDoc has the advantage of providing a go to source definition feature for TypeScript users.
This allows users to verify that library code is safe and is a great help for debugging and contributing if a bug occurs.

Collapse
 
efpage profile image
Eckehard

No, that´s not the point. I hate to know that my code is full of hidden errors and can break anytime. It´s more a feeling that Typescript does not solve the problem in the same way, a full featured compiled language did. But this is not typescripts fault, it is more a price you pay, if you use an interpreted language.

Collapse
 
andrzej_kowal profile image
Andrzej Kowal

I definitely fully agree with @mellis481. Article sounds as a joke. TypeScript is the one of the best things which happen with JavaScript world for last 10 years. JSdoc looks like a weird workaround, while typescript gives many great mechanisms and utilities to supply codebase with advanced types including generics. Not that much time ago I heard about Bun. It’s a promising game changer that hopefully will decrease amount of “setup” work of typescript and will greatly speed up (hopefully). And even with all the cons of TypeScript - it’s one of the best (and proven to be the best) tools which everyone should use.

Collapse
 
artxe2 profile image
Yeom suyun

I somewhat disagree with the arguments about Bun, but I definitely agree with the arguments about TypeScript.
However, JSDoc is fully supported by TypeScript for type checking, and there are definitely significant benefits to adopting it.

Collapse
 
abhishekvash profile image
Abhishek S

I believe JSDoc is not really a silver bullet. Typescript isn’t either, but for the most part, it’s a lot more usable than JSDoc. For one, it’s cleaner. JSDoc makes me retch. And two, I think it’s easier to have less experienced developers adopt TS over JSDoc since it resembles strongly typed languages they would’ve used before. And as for build times? I think developer time is more expensive than machine build times, and in that sense, time wasted writing verbose comments in JSDoc costs the company more than what a TS compilation does.

Collapse
 
ctsstc profile image
Cody Swartz • Edited

Why not instead use something like Flow? Why not use a build tool that skips type checking?

Typescript used to be about so much more than just types. It used to provide a feature set on top of JS that it was missing such as decorators, classes, private and public accessors to methods, and more. JS has caught up quite a bit over the years, but still isn't great in some of the features.

I would still much rather write a class in TS that looks closer to C# than write one in plain JS right now, but it is possible now days so I appreciate that. I would still rather have keywords like private and public rather than prefix with # for private access.

There are now ways to spin up Typescript projects effortlessly, or utilize TS first runtimes like Deno or Bun. I just don't get why so many are ready to abandon ship, and why others are acting like JS doc ran through a TS language server is "new" this feature has been part of VSCode for quite some time. It used to be a feature you had to enable first or maybe your still do? The irony is that it's still using TS as the language server, but it's more isolated and without a large transpilation step.

Things have come a long way, but I too am not super happy with the whole ecosystem of transpiling through to Jest and the pains of ESM. Hopefully runtimes like Deno and Bun inspire a better Node ecosystem, or maybe it's time to embrace them.

Collapse
 
steffennilsen profile image
Steffen Nilsen

It does happen that I experience typescript friction, but it tends to be self inflicted and particularly from being too clever with the types. I have found myself deleting complicated types and rewritten them in a simpler manner.
I'm fairly certain most of the friction can be solved with improved tooling, in the IDE the issues are reported with rather complex output from tsc, there's room for improvement here.

Collapse
 
artxe2 profile image
Yeom suyun

Sure, if we feel that the TypeScript mindset is different from JavaScript, it might be a sign that the types are wrong.
Types are helpers, not blockers.

Collapse
 
overflow profile image
overFlow

before i even read it further. i am a proponent of learning one thing and one thing only. and that thing is JS. i went through a Typescript lesson and i kinda felt like people are just creating languages just for the fun of it and making reasons that do not make sense to me...
typescript is JavaScript. What do the javascript guys got to say perhaps for copyright infringement.

I was thinking the other day:"What if the JS guys institute and ability for Types in JS if its not already available. Then what of typeScript?

Collapse
 
shayes profile image
Shayes

This is just a manifestation of the "static vs dynamic typed languages" debate which has existed for ages. Do you make the code safer with a bigger learning curve, or do you make it easier with a lower learning curve? In my opinion, static types are usually worth the struggle.

Collapse
 
fuzzhd profile image
Justin Condello

I was doing code conversion from Java to JavaScript. I had the opportunity to use TypeScript instead but I couldn't wrap my head around it. Then, when using IntelliJ, I learned about JSDoc. At that point, I just fed all the functions and classes for my project to ChatGPT to generate the JSDoc. I touched up some of the comments from GPT to expand out some descriptions. And like magic, IntelliJ started to show much more useful hints and made coding much easier.

Collapse
 
nikunjbhatt profile image
Nikunj Bhatt • Edited

This is like - which programming language is good?, and the answer is - a good programmer can write good code even in a bad language, and a bad programmer would write bad code in a good language. 😄

I don't like compiling step. JDoc also shouldn't use TS, it should use plain JS, otherwise it is better to use TS.

JS evolution is very slow, I am eager to see all good things directly implemented in JS. Or browsers or the makers of these libraries should provide extensions which can run TS and SCSS like stuffs directly.

Collapse
 
artxe2 profile image
Yeom suyun

Programmer communities seem to particularly enjoy arguments like "n reasons why you should or shouldn't use ~~."
It will be difficult for browsers to support TS. This is because Chrome is owned by Google and TS is made by MS.
If Edge had a market share of 1st, it might have been different.

Collapse
 
momodev profile image
Santiago G. Marín

And who will keep the JSDocs up to date?

Collapse
 
alanxtreme profile image
Alan Daniel

JSDoc looks horrible! What a terrible DEV Experience IMO. Why not just wait until JS adapt types natively and meanwhile use TS?

Collapse
 
shroomlife profile image
shroomlife 🍄

worst title and image ever. since chatgpt types are no longer unproductive... IMHO

Collapse
 
msveshnikov profile image
Max Sveshnikov

JSDoc is absolutely the same crap like TS itself. I use no one. Just pure JS. Types are not needed at all 😎

Collapse
 
lassazvegaz profile image
LassazVegaz

Adding types as comments is productive than TS? Funny
People will miss TS again when the deployed code crashes because x is not a property of undefined and y is not a function and etc…

Collapse
 
tharsiscampos profile image
tharsiscampos

"Throw away Typescript for small projects, only". That should be the title to this post.

Collapse
 
artxe2 profile image
Yeom suyun

Using JSDoc does not mean throw away "TypeScript".
Here is an example of using JSDoc in TypeScript playground, and I am considering writing another article about this.

Collapse
 
vandermannmusic profile image
Vandermann • Edited

Personally I really don't feel that JSDoc is as readable as TS. I work on a very large enterprise application using Typescript and would not want us to move to JSDoc.

Collapse
 
howesteve profile image
Steve Howe

Let's see you write something like zoo or typeirm with plain js.