tc39 / proposal-type-annotations

ECMAScript proposal for type syntax that is erased - Stage 1
https://tc39.es/proposal-type-annotations/
4.26k stars 46 forks source link

Arguments in favor of abandoning/rejecting this proposal. #134

Closed lillallol closed 2 years ago

lillallol commented 2 years ago

Before attempting to counter argue with me, please try what I suggest.

ECMAScript proposal: Type Annotations

This proposal aims to enable developers to add type annotations to their JavaScript code, allowing those annotations to be checked by a type checker that is external to JavaScript. At runtime, a JavaScript engine ignores them, treating the types as comments.

The aim of this proposal is to enable developers to run programs written in TypeScript... without any need for transpilation, if they stick within a certain reasonably large subset of the language.

Trends in JavaScript Compilation

... This proposal will reduce the need to have a build step which can make some development set-ups much simpler. Users can simply run the code they wrote.

This is already possible. You just have to write all your types in .ts files and then import them via JSDoc comments in the .js files (do not forget to use "allowJs": true,"checkJs": true,include : ["./**/*.js"] and maxNodeModuleJsDepth in your tsconfig).

Limits of JSDoc Type Annotations

This section of the proposal did not mention importing types from .ts files via JSDoc comments. The section should be extended with this example:

//types.ts
export type IStringsStringStrings = (p1: string, p2?: string, p3?: string, p4? : string, ) => string;

//index.js
/**@type {import("./types").IStringsStringStrings} */
function stringsStringStrings(p1, p2, p3, p4 = "test") {
    // TODO
}

...JSDoc comments only provide a subset of the feature set supported in TypeScript

The question is not whether JS should have types, but rather "how should JS work with types?" One valid answer is that the current ecosystem provides sufficient support where types are stripped out separately ahead-of-time, but this proposal may provide advantages over that approach.

Regarding importing .ts types via JSDoc comments in .js, which are these missing features (when compared to the features of this proposal)?

...JSDoc comments are typically more verbose

You have to type /*@type {}**/ and then the intellisense for importing types will work. It is not that much of a big deal regarding verbosity especially given the fact that like this you avoid the drawbacks of compiling .ts to .js, and also you do not need a new proposal that will make JavaScript parsing slower.

This proposal will require work from both ECMAScript and TypeScript itself, where ECMAScript expands its current syntax, but TypeScript makes certain concessions so that types can fit into that space.

There is no such need when importing types from .ts to .js files via JSDoc comments.

Why not stick to existing JS comment syntax?

Although it is possible to define types in existing JavaScript comments, as Closure and TypeScript's JSDoc mode do, this syntax is much more ... unergonomic.

This is a biased opinion that is not true. With importing types from .ts to .js files via JSDoc comments you can get all the benefits of this proposal without the need to introduce a new proposal and without the need to change existing JavaScript parsers (client or not) and make them slower. Finally forcing separation of abstractions and concretions is a good practice.

Consider the fact that JSDoc type annotations were present in Closure Compiler prior to TypeScript, and that TypeScript's JSDoc support has been present for years now. While types in JSDoc has grown over the years, most type-checked JavaScript is still written in TypeScript files with TypeScript syntax.

MyQki

Why did TypeScript support writing concretions in .ts files in the first place? That was a major mistake, that further fragmented the ecosystem and added an extra build step. The fact that we did/promoted a mistake in the past is not a valid argument in favor of continuing this mistake in present and future.

dfabulich commented 2 years ago

JSDoc syntax does work (with some missing pieces), and you agree that JSDoc annotations are more verbose than TypeScript/Flow annotations, but you say that "It is not that much of a big deal regarding verbosity."

What is and isn't a "big deal regarding verbosity" is a matter of values. Verbosity might not matter to one person, and it might matter a lot to another person. But, in fact, lots of people do think that JSDoc's verbosity is a big deal; it's such a big deal that the TypeScript, Flow, and Hegel teams all decided to fork JavaScript in order to build the language they want. As the proposal explains,

TypeScript was currently listed as the 4th most-used language in GitHub's State of the Octoverse, and on Stack Overflow's Annual Developer Survey it has been listed in both the top 4 most-loved languages since 2017 and the 10 most-used languages.

But that then brings us to the problem statement for this repository, which was presented at TC39:

The strong demand for ergonomic type annotation syntax has led to forks of JavaScript with custom syntax.

This has introduced developer friction and means widely-used JS forks have trouble coordinating with TC39 and must risk syntax conflicts.

Maybe you think all of those TypeScript and Flow developers are being unwise, and that they all should have written their types in JSDoc, in order to skip a compilation step. (Why don't they realize that the verbosity of JSDoc is actually no big deal?!)

But that doesn't solve the problem: there is demand in the ecosystem for ergonomic type annotation syntax (like TypeScript, and not like JSDoc). We can say "there shouldn't be demand in the ecosystem for TypeScript annotations, because JSDoc's verbosity is no big deal" but that won't make the demand go away, and it certainly won't make the forks go away.

Adopting ergonomic type annotation syntax in JavaScript is the only way to end the forks. Telling TypeScript developers that their preferences are incorrect didn't work in 2017, and it isn't gonna work today, when TypeScript is more popular than ever.

lillallol commented 2 years ago

@dfabulich

JSDoc syntax does work (with some missing pieces)

I posed the following question:

Regarding importing .ts types via JSDoc comments in .js, which are these missing features (when compared to the features of this proposal)?

which remains unanswered. I do not understand why this proposal (and people) compare JSDoc to full TS, and not the proposal itself. And just to be crystal clear here, JSDoc is irrelevant. What I am actually talking about is importing types via comments. JSDoc happens to currently enable that.

Maybe you think all of those TypeScript and Flow developers are being unwise, and that they all should have written their types in JSDoc, in order to skip a compilation step.

Yes, they should have imported types in JS via comments. That is what should have been done from the beginning, because it is objectively better:

  1. No need to wait for the compiler
  2. No need to deal with the fragmented ecosystem of ts to js compilation
  3. No need to depend on extra packages (ts-jest,ts-node,esbuild,tsc,ts-loader,etc.) for your code to get executed
  4. No need to learn the new APIs (a non transferable knowledge) of those extra packages
  5. Less security issues due to less need of npm packages
  6. No need for developers to waste their time developing better and faster compilers
  7. One less build step
  8. One less config in the the mess of configs (webpack, cjs to esm, monorepo, storybook etc) that do not play well together, so we are one step closer for developers to not waste weeks to make them work together
  9. You can copy and paste the code in the console and it will execute
  10. Reduced need for .d.ts files
  11. No need to introduce new import/export that are not compatible with esm
  12. Reduced need for source maps
  13. You code executes as you have written it (at least in the development stage)
  14. typescript maintainers need to do considerably less work, since tsc will act only as a linter and there is no need to act as a compiler
  15. reduced need for .d.ts bundling
  16. (edit :) this way of static typing punishes you with verbosity when you deviate from the best practice of separating intention from implementation, and hence you will be forced to stick to the best practices, something that does not happen (even worse embraced) with the .ts compile to .js method
  17. (edit :) it is actually less verbose (yes you are reading this right, given that you stick to the best practices)
  18. (edit :) your .js files are not hard coded with types so this : /**@type {import("./some/path/without/ts/extension").IMyType}/, can be universally used by TS, Flow, etc
  19. (edit :) TS, Flow etc can use whatever syntax they want without worrying that it will not be compatible with JS

Importing types via comments has actually no intrinsic disadvantages when compared to compile .ts to .js method.

I hope that now it is clear that these people are unwise. They are the very reason the JavaScript ecosystem is a fragmented mess.

Are we going to take seriously these people? Of course not. Unless you want to fragment more the ecosystem.

And lets not forget that experienced people have talked about promotion driven development, i.e. some people create virtual problems to justify their existence and salary increase.

(Why don't they realize that the verbosity of JSDoc is actually no big deal?!)

Because they have never tried it, because resume/hype/promotion driven development, because: that is how things are done around here, because they do not want to admit their mistakes.

It is clear from what I have said before that they are objectively wrong.

But, in fact, lots of people do think that JSDoc's verbosity is a big deal; it's such a big deal that the TypeScript, Flow, and Hegel teams all decided to fork JavaScript in order to build the language they want.

The strong demand for ergonomic type annotation syntax has led to forks of JavaScript with custom syntax.

there is demand in the ecosystem for ergonomic type annotation syntax

There is absolutely no evidence that there such a demand. And if there is, there is absolutely no evidence that it is unbiased. If we are really interested in a proper statistical result on what people prefer, then we should ask people that have been forced to write projects with both ways of static type checking and not just only one of them (like for example people like me). Anything different from that will give a biased answer.

Just to be crystal clear again. No I am not advocating for writing types in JSDoc. I am advocating for importing .ts types in .js files via comments. The majority of people do not actually understand that so they make wrong assumptions.

We can say "there shouldn't be demand in the ecosystem for TypeScript annotations, because JSDoc's verbosity is no big deal" but that won't make the demand go away, and it certainly won't make the forks go away.

Adopting ergonomic type annotation syntax in JavaScript is the only way to end the forks

No it is not the only way to end the forks. If the influencers (TS, and those who make forks of JS) admit their mistake and push/promote the objectively better solution which is importing types with comments, then the hype-driven people (i.e. the overwhelming majority) will start using this way of static type checking (not necessarily because they understand that is objectively better but because it is the next big thing).

Edit : We have to admit that is how the JS ecosystem works. It is hype driven. This is coming from the mouths of seniors, not by me.

Static type checking is not a problem anymore in JS. Ending hypes that promote objectively inferior ways of developing, is. And that is because it leads to fragmentation of JS ecosystem, and hence more time wasted for the JS developer (experienced or not). And that developer can be anyone (including me), because we might be asked to support legacy JS or be given a code base that we have not written.

Type imports with comments are objectively more ergonomic than what this proposal suggest and here is why:

  1. no need to make the JS parser slower (client or server)
  2. no extra work for tc39
  3. no need for proposals, the solution already exists
  4. no need to change JS language
  5. same static type checking as the proposal
  6. (edit:) no need to introduce a hybrid form of TS that has breaking changes (look at generics)
  7. (edit:) no need to force people to use TS to enable static type checking since the types can be imported from e.g. Flow files
  8. (edit:) point 16 and 17 mentioned before

We will make the JS parser slower for both client and server because hype driven people have been used to writing concretion in .ts. This is absurd.

Telling TypeScript developers that their preferences are incorrect didn't work in 2017

What are you talking about?


Climb the ladder man, enjoy the bananas. There is nothing wrong with that. It is clear that no water drops anymore.

Abandon this proposal.

People who down vote me, prove me wrong with objective arguments and not with just what is in hype currently. Hypes come and go.

Typescript maintainers if you are reading this why did you enable writing concretions in .ts files in the first place?

benjamingr commented 2 years ago

which remains unanswered. I do not understand why this proposal (and people) compare JSDoc to full TS, and not the proposal itself. And just to be crystal clear here, JSDoc is irrelevant. What I am actually talking about is importing types via comments. JSDoc happens to currently enable that.

This would not address the use case this proposal attempts to solve at all. Most people are not going to want to write:

//types.ts
export type Point = { x: number, y: number };

//index.js
/** @type {import("./types").Point} */
const x = getPointWithMaybeMoreProperties();

Over:

//index.js
const x: { x: number, y: number } = getPointWithMaybeMoreProperties();
// or
type Point = { x: number, y: number };
const x: Point = getPointWithMaybeMoreProperties();
lillallol commented 2 years ago

@benjamingr

I am honestly not gonna repeat the arguments that I have already written (not even copy paste them).

benjamingr commented 2 years ago

Ok, thanks for your feedback on the proposal. It will be taken into consideration 🙏