microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
99.26k stars 12.31k forks source link

Typescript type annotations as comments #9694

Open nojvek opened 8 years ago

nojvek commented 8 years ago

Typescript’s goal is simply be Javascript + Types.

There are many use cases where one might want to use the excellent typechecker but not really have any emit stage.

Projects already written in javascript work with allowJS. Typescript already supports parsing types from jsdoc comments.

What would be really awesome is just comment annotating your javascript with types and the project gets the benefit of being type checked. This could be a boon for a lot of existing javascript projects. Getting intellisense, VSCode typechecking on the fly and a lot of language server awesomeness.

e.g.

/// <reference path="..." />

class Hello {
    /*:: private*/ hello(message /*: string*/) /*: Promise<{}>*/{
                const promise /*: Promise<void>*/ = null 
        return /*:: <Promise<{}>>*/ null;
    }
}

i.e

/: [type] */ /:: [tscode] */

nojvek commented 8 years ago

https://flowtype.org/blog/2015/02/20/Flow-Comments.html

Flow has a descent spec. It was a major feature request on their end too.

I think the big value add is typescript's language service. Being able to annotate an existing js code base and get on the fly error checking + code completion is pure awesomeness.

No source mapping needed, Browser/node reads the same code. Don't need to wait for a transpiling step. Node_modules written in this flavor don't need a separate typings install since source+types is same file.

pardonmyenglish commented 7 years ago

+1 I really love this aspect of flow and wish that TS supports something similar.

eggers commented 7 years ago

I haven't used it myself, but since 2.0, TypeScript supports jsdoc for typedef: JSDoc support in JavaScript

pardonmyenglish commented 7 years ago

In my view, the difference is that the JSDoc approach does not resemble the standard TS approach. Take the example in the tutorial: http://www.typescriptlang.org/docs/tutorial.html

function greeter(person) {
    return "Hello, " + person;
}

The recommended TS according to the docs:

function greeter(person: string) {
    return "Hello, " + person;
}

The comment-based approach that flow supports really resembles what you would write -- the type annotation is basically wrapped in a C-style comment:

function greeter(person/*: string*/) {
    return "Hello, " + person;
}

The JSDoc approach technically supports this case, but it is very different from the canonical TS approach:

/**
 * @param {string}  person  
 */
function greeter(person){
    return "Hello, " + person;
}
nojvek commented 7 years ago

You are correct. Jsdoc has a lot more verbosity than flow style comments.

On Wednesday, December 14, 2016, pardonmyenglish notifications@github.com wrote:

In my view, the difference is that the JSDoc approach does not resemble the standard TS approach. Take the example in the tutorial: http://www.typescriptlang.org/docs/tutorial.html

function greeter(person) { return "Hello, " + person; }

The recommended TS according to the docs:

function greeter(person: string) { return "Hello, " + person; }

The comment-based approach that flow supports really resembles what you would write -- the type annotation is basically wrapped in a C-style comment:

function greeter(person/: string/) { return "Hello, " + person; }

The JSDoc approach technically supports this case, but it is very different from the canonical TS approach:

/* @param {string} person */function greeter(person){ return "Hello, " + person; }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/TypeScript/issues/9694#issuecomment-267244539, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-JVH1GfPO_GWAXT_fmBeb4qedUwNqJks5rINRcgaJpZM4JLxhT .

akdor1154 commented 7 years ago

It seems there is often resistance to adding a build step in projects where previously was none - at my workplace I am using Flow to provide static analysis over Typescript precisely because of this, and the amount of community support this feature has in Flow suggests this scenario is reasonably common. If Typescript supported annotations in comments I believe it would pick up a lot of this use, as it's generally considered on the whole to be more powerful than Flow. I know I'd rather use it. This also shouldn't be specific to Salsa (I guess), my dream implementation of this feature would be that tsc or a ts language service in my IDE of choice would just load .js files with TS comments and treat them as if they were typescript.

nojvek commented 7 years ago

Totally agree with this.

JS with typed comments definitely makes js more powerful.

On Mon, Jan 9, 2017 at 9:23 PM Jarrad Whitaker notifications@github.com wrote:

It seems there is often resistance to adding a build step in projects where previously was none - at my workplace I am using Flow to provide static analysis over Typescript precisely because of this, and the amount of community support this feature has in Flow suggests this scenario is reasonably common.

If Typescript supported annotations in comments I believe it would pick up a lot of this use, as it's generally considered on the whole to be more powerful than Flow. I know I'd rather use it.

This also shouldn't be specific to Salsa (I guess), my dream implementation of this feature would be that tsc or a ts language service in my IDE of choice would just load .js files with TS comments and treat them as if they were typescript.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/TypeScript/issues/9694#issuecomment-271489470, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-JVH482DM1OpASNYEEGF-gmH_-XD2_ks5rQxXcgaJpZM4JLxhT .

akdor1154 commented 7 years ago

First shot at implementing this. It currently only looks at .ts files (pretty useless, we need it to work with .js). It may also benefit from some equivalent of //@flow, otherwise ts is likely to go parsing everything it can find in node_modules. However, the basic functionality is there and working.

abenhamdine commented 7 years ago

IMHO, I think this feature is not very necessary (and this is also for future readers who would were eagerly looking for this feature).

At the beginning, I was also shy to add a compilation step in our projects, and considered using Flow only for the benefit of comment syntax. But a few tries whith ts, I realized that :

Otherwise, you juste have to rename .js file to .ts file in order to have type checking.

FWIW, our project is a very complex application developped with node and extjs, and we migrate nearly 60% of server code to Typescript in 2 weeks.

nojvek commented 7 years ago

Thanks for your feedback Arnaud.

This is a very polarizing discussion. I'll list some arguments I have experienced and got from friends at other companies.

Argument 1: From the fundamentals Isn't Typescript just javascript + types? If so, then one would expect their javascript to remain as is and just add types in their js code. All major browsers and node support es6 in their latest version. Having plain js works. Transpilation is overkill. Node modules could benefit from it. JS libraries could benefit. It's only when you're stitching code that webpack is needed. With http2 push https://en.m.wikipedia.org/wiki/HTTP/2_Server_Push even stiching into one big js isn't needed.

Argument 2: vscode js experience that uses the tsserver gives a very handicapped experience for js compared to ts. If js is the lingua franca of the Web then it makes sense to give javascript the nice experience. Jsdoc/closure comments/flow comments are all efforts to make js powerful.

Argument 3: Dealing with sourcemaps is a PITA. Because of the reverse mapping step, the stars need to align for debuggers to get everything right. I've given up many times finding the exact setup and simply moved to just debug the generated js. Many tools do a half arsed Job with sourcemaps. See: https://github.com/Microsoft/vscode/issues/18363

⋅⋅⋅ Found the issue. Well, found a fix. The issue is that no one understands sourcemaps. Neither do we nor anyone who develops libraries for sourcemaps. ⋅⋅⋅

Argument 4: Browser devtools have a great feature of live edit. A class of problems go away if source is what the engines run. Testing iterations with live edit is instantaneous. A transpile step breaks the dev loop. Can't copy a ts function into console to test something quick. Browsers barf at the type syntax. JS exceptions don't map to the source. We have to do that manually.

In a way what we really need is browsers and node to run javascript with type hints. Python does that by ignoring the type hints https://www.python.org/dev/peps/pep-0484/. May be Ecma will someday approve of type syntax. JS engines will do the correct thing with types. Until then, a commented syntax would be handy. A great js editing experience would increase developer productivity.

On Thu, Jan 12, 2017 at 6:08 AM Arnaud Benhamdine notifications@github.com wrote:

IMHO, I think this feature is not very necessary (and this is also for future readers who would were eagerly looking for this feature).

At the beginning, I was also shy to add a compilation step in our projects, and considered using Flow only for the benefit of comment syntax. But a few tries whith ts, I realized that :

  • the compilation step in Typescript is quite fast, simple and reliable

  • the js code generate is very readable. Actually, the code transpiled by Typescript is nearly the same that i would have written ! (minus some line breaks removed, etc...). It means that if you want, at any moment, you could stop using ts, and revert back to the js files.

You juste have to rename .js file to .ts file in order to have type checking.

FWIW, our project is a very complex application developped with node and extjs, and we migrate nearly 60% of server code to Typescript in 2 weeks.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/TypeScript/issues/9694#issuecomment-272171576, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-JVIjPMSnz__hbsnZROGzIpcjJbrrMks5rRjPTgaJpZM4JLxhT .

abenhamdine commented 7 years ago

Thx for you detailled answer !

I have to admit your arguments are quite valid, and probably my feedback too brief (mainly because I'm not a native english speaker).

My feedback is more "hey, you can jump into ts without syntax comment, you should not choose beetween TS and Flow just basing your decision upon the existence of this syntax in Flow". Because it was exactly the situation where we were two months ago.

Concerning sourcemap, so far, we didn't have too much problems in VSCode. For instance, node debugging has always run perfectly (while again : it's a very complex project). And in case of error in prod, it's not so too difficult to map the .js line to the .ts line (even if it's indeed a waste of time).

However, we have only migrated server code to ts, we don't consider migrate browser code at the moment.

An other caveat is indeed the use of VS Code for editing .js files : we used to be on ST3 for js files, and we switched to VS Code after a poor experience with ST Typescript plugin. We found VS Code less fast and convenient than ST is. However, VS Code is evolving quickly, and in the right direction IMO.

aluanhaddad commented 7 years ago

Then there will be two type syntaxes embedded in comments, actually three if you include Flow types. JSDoc already has multiple interpretations. Throw TypeScript types into comments and even more complexity is introduced.

nojvek commented 7 years ago

Want to clarify. I don't think commented types in Typescript bring much benefit. As you said it just introduces complexity.

Commented types in javascript (.JS) are useful. In that scenario, there are only two types. Jsdoc and flow.

Flow types are just Typescript types wrapped in comments.

E.g /:string/ and /::/(someValue)

This means having a tsconfig with allowJs should give a very close experience to Typescript. Both type checker and vscode ide.

On Fri, Jan 13, 2017 at 12:17 AM Aluan Haddad notifications@github.com wrote:

Then there will be two type syntaxes embedded in comments, actually three if you include Flow types. JSDoc already has multiple interpretations. Throw TypeScript types into comments and even more complexity is introduced.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/TypeScript/issues/9694#issuecomment-272385951, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-JVOwvwdI_N1Y2UeK7PcF1LuMp0PFdks5rRzMRgaJpZM4JLxhT .

aluanhaddad commented 7 years ago

Want to clarify. I don't think commented types in Typescript bring much

Thanks I wasn't sure if this was intended to apply to JavaScript and TypeScript or just JavaScript.

Commented types in javascript (.JS) are useful. In that scenario, there are only two types. Jsdoc and flow.

Perhaps but there are different interpretations of JSDoc, TypeScript is one interpretation, Closure is another, JSDoc v3 is yet another.

Flow types are just Typescript types wrapped in comments.

E.g /:string/ and /::/(someValue)

I so wish that were true. Unfortunately the syntax is subtly different. More significantly the meaning can be radically different.

This means having a tsconfig with allowJs should give a very close experience to Typescript. Both type checker and vscode ide.

That would be a great indeed.

zspitz commented 7 years ago

@aluanhaddad Could you provide some examples of the differences between the three flavors of commented types?

aluanhaddad commented 7 years ago

Flow:

type T = { name: string }
Array<U: T>

TypeScript:

type T = { name: string }
Array<U extends T>

JSDoc:

@typedef T { name: string }
@template U implements T
Array<U>

The difference in interpretation is more what I'm concerned about.

aluanhaddad commented 7 years ago

That last example is not yet supported by closure and I'm not even sure if that's how you would write it it's hypothetical syntax

pardonmyenglish commented 7 years ago

@aluanhaddad I think you are confused about the proposal. The idea isn't to introduce the exact flow syntax into typescript, but rather to introduce a special comment form which JS engines ignore but tsc and typescript parsers interpret as valid TS code.

I gave an example in https://github.com/Microsoft/TypeScript/issues/9694#issuecomment-267244539 but it wasn't that clear so I will try another example from the tutorial.

Let's say you have an existing JS codebase:

function greeter(person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

var user = { firstName: "Jane", lastName: "User" };

document.body.innerHTML = greeter(user);

The TS form that defines the person interface looks like:

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

var user = { firstName: "Jane", lastName: "User" };

document.body.innerHTML = greeter(user);

The comment form which we are discussing is a series of comments atop the JS form that aligns with the TS form:

/*::
interface Person { // <-- this is the same exact code you would write if you fully bought into TS
    firstName: string;
    lastName: string;
}
*/
function greeter(person/*: Person*/) { // <-- the type annotation is in a C-style comment that JS ignores but TS would parse
    return "Hello, " + person.firstName + " " + person.lastName;
}

var user = { firstName: "Jane", lastName: "User" };

document.body.innerHTML = greeter(user);

The ability to write snippets of typescript and embed them in comments would enable developers to slowly annotate their JS code without changing their minified JS output and without having to buy into TS from the onset. This is important for adoption. We ended up adopting flow for a 50kloc JS project because it was incredibly easy to demonstrate the power of flow and incremental type annotations without actually changing the existing workflows or existing live JS.

aluanhaddad commented 7 years ago

I am sorry, I am not trying to be stubborn. I do understand the use case and I agree it is both valid and valuable. I am talking about the way tools behave. If a tool uses a heuristic to find Flow types in comments, it could choke on this. The same is true for JSDoc, but this is probably easier to disambiguate.

akdor1154 commented 7 years ago

@aluanhaddad a heuristic to pick up flow types would be unlikely to pick up these hypothetical typescript types by mistake - flow-annotated-js needs to contain a // @flow comment to trigger processing.

nojvek commented 7 years ago

Agree with @pardonmyenglish. Typescript doesn't need to understand every syntax out there. It just needs to enable a typechecking scenario for javascript files.

With this Tsserver can support the magic of refactoring, code completion, etc for Javascript files

On Sat, Jan 14, 2017 at 5:25 PM Jarrad Whitaker notifications@github.com wrote:

@aluanhaddad https://github.com/aluanhaddad a heuristic to pick up flow types would benefit unlikely to pick up these hypothetical typescript types by mistake - flow-annotated-js needs to contain a // @flow comment to trigger processing.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/TypeScript/issues/9694#issuecomment-272666510, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-JVGS43w9vnxsUXLvV0-ZGkgOToPkAks5rSXWJgaJpZM4JLxhT .

abenhamdine commented 7 years ago

And in case of error in prod, it's not so too difficult to map the .js line to the .ts line (even if it's indeed a waste of time).

For the future reader : I correct myself, with https://github.com/evanw/node-source-map-support, we can have the line number in the .ts file, and it works perfectly for us.

pitaj commented 7 years ago

Any updates on this?

Is there a way to implement this as a plugin or something? I'm thinking of just pushing the source code through something like this:

return source
  .replace(/\/\*::([\s\S]*?)\*\//g, '$1')
  .replace(/\/\*:([\s\S]*?)\*\//g, ':$1');

and then passing that to TS, but I'm primarily focused on VS Code support

nojvek commented 7 years ago

I do like function syntax e.g

function hello(greeting /*: string */, notify /*: boolean */) {
}

Rather than jsdoc comments which are verbose and require duplication of param name.

Currently not supported but I feel that it should be pretty easy to add.

https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript

flobacher commented 6 years ago

any update on this? support for this would greatly reduce the hurdle for JS devs to get started with typescript while being not so verbose and awkward to write as jsdoc comments

nojvek commented 6 years ago

I have been told on multiple occasions that TS team is not willing to take on this feature. It introduces another syntax which is another path of syntax the TS team will need to maintain.

@mhegazy could probably elaborate on this.

I personally find jsdoc syntax too verbose to use it.

What I would love to see is the tc39 committee actually bringing type hints to actual js parsing spec. Close to how python does it with https://www.python.org/dev/peps/pep-0484/.

That means I can just write javascript with types and interfaces. No weird comment syntax. The JS engines will just ignore the type hints like how babel typescript preset does its thing.

flobacher commented 6 years ago

@nojvek I agree having types and interfaces ignored by the js parser would be the best, but I guess that will not happen (if ever) very soon.. =/

mleg commented 6 years ago

Dear core typescript developers, thank you for such a high quality tool you made. But if you only could imagine how we, typescript users, desperately need the feature discussed... You've done so much and what's left is so little.

Paxa commented 6 years ago

It is possible with some hacks:

var ts = require("typescript");

var fileNames = [
  'myfiles.js'
];

var options = {
  allowJs: true,
  checkJs: true,
  noEmitForJsFiles: false,
  target: ts.ScriptTarget.ES2017,
  noEmit: true, // don't write compiled files 
  allowNonTsExtensions: true,
  moduleResolution: ts.ModuleResolutionKind.NodeJs,
  module: ts.ModuleKind.ES2015
};

// patch ts.createSourceFile to convert flow-style comments in .js files
var createSourceFileOrig = ts.createSourceFile;
ts.createSourceFile = (fileName, text, languageVersion, setParentNodes) => {
  if (fileName.match(/\.js$/)) {
    text = text.replace(/\/\*::([\s\S]+?)\*\//gm, '$1');
    text = text.replace(/\/\*:(.+?)\*\//gm, ':$1');
  }
  return createSourceFileOrig(fileName, text, languageVersion, setParentNodes);
}

// make typescript thing that .js files are same as .ts
//   (otherwise it will validate them as js files)
var ensureScriptKindOrig = ts.ensureScriptKind;
ts.ensureScriptKind = (fileName, scriptKind) => {
  var ext = fileName.substr(fileName.lastIndexOf("."));
  return ext == '.js' ? 3 : ensureScriptKindOrig(fileName, scriptKind);
};

// run and print results
let program = ts.createProgram(fileNames, options);

let emitResult = program.emit();
let allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);

allDiagnostics.forEach(diagnostic => {
    if (diagnostic.file) {
        let res = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
        let line = res.line, character = res.character;
        let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
        console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
    } else {
        console.log(`${ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`);
    }
});
weswigham commented 6 years ago

@Paxa nowadays we actually parse and check jsdoc-style type annotations in js (which I'd recommend over jamming ts-in-comments into a js file):

// @ts-check
/**
 * @type {function(number): undefined}
 */
const x = x => void 0;
x("ohno"); // will error

so there's a builtin syntax available to add type annotations in JS - we just wanted to support what already had a rather broad community, rather than introducing a new style of semantic comments for no reason other than not really liking the style of the other (which is what a lot of the more recent comments in this thread are gripes about). Plus, jsdoc is a little more natural when you've already used js a lot - the inline-code-comment style is more like "I'm already familiar with TS but am being forced to write JS, woe is me".

nojvek commented 6 years ago

Jsdoc types in js is very fragmented though. 90% of the time vscode gets the wrong type. We can’t import .d.ts types in js files like TS can.

TS has a lot of strictness when you declare a certain type. Jsdoc seems to silently fail.

I did submit a TS -> jsdoc equivalent PR a while back but it never made it.

As someone that loves JS but also loves Typescript vscode autocomplete + checking/refactor abilities, having a guarantee that every Typescript feature has a jsdoc equivalent is a massive boon.

weswigham commented 6 years ago

Jsdoc types in js is very fragmented though. 90% of the time vscode gets the wrong type. We can’t import .d.ts types in js files like TS can.

Actually with 2.9 (which should have an RC cut soon, if not already) you can.

/** @typedef {import("some-declaration-file-module").Foo} Foo */

TS has a lot of strictness when you declare a certain type. Jsdoc seems to silently fail.

Please elaborate - we're trying to find and fix any holes like this.

Paxa commented 6 years ago

Thanks @weswigham I think it depends on personal syntax preferences. I like compact syntax more. Currently I find it more comfortable to convert project slowly, file by file and add type annotations only when necessary.

nojvek commented 6 years ago

@weswigham here's a philosophical take on Typescript. Its a great language and does amazing things, but its not Javascript. You can't copy paste and run it on a console, or let the browser/node run it directly. It needs to be transpiled in some way. Javascript is the lingua franca of the web and will remain so for a while. What is lacking in javascript is a great input/output contract for functions, modules and classes. Kind of like a C/C++ .h header files. That's how I see .d.ts files in npm packages and @types org. At the root I believe a big fundamental need is: A specification of a contract for js libs.

1) Jsdoc is great, but strict jsdoc would be awesome. If I have // @ts-check, no types should slip through. Unresolved types should error. Vscode gives excellent code completion on jsdoc and shows squigglies if something is not valid. (not sure if something changed recently, but jsdoc types seemed loose when I last played with it)

2) Import multiple types like /* @import {X, Y, Z} from './hello.d.ts' */. /** @typedef syntax is a step down from excellent "import only what you need" philosphy of ES6.

3) Being able to define a module types contract in .d.ts file and ensure corresponding JS is compliant to it. Kind of like /* @implements SomeInterface */ for modules and classes.

4) Automatically build .d.ts files with --emitDeclarationsOnly from combination of js files and .d.ts files. Puppeteer and other projects have been wanting this for a long time. It doesn't make sense to hand maintain npm types .d.ts files if they can be generated from jsdoc.

Basically, if typescript ships with a solid JS typechecker and .d.ts generator story, the way most JS projects are written fundamentally changes. Rather than a .d.ts being an after thought in npm @types, more projects see value in just making it part of the project since its easy. More projects adopt typechecking since its not disruptive.

akdor1154 commented 6 years ago

Was getting all ready to fire up a response and found @nojvek had already written nearly everything I wanted to write.

Getting the basics of typescript checking supported with JSDoc is great, and it's really cool to see what the team has achieved so far. However, the long tail of less common features is still (and always will be) a problem. Off the top of my head, I cannot write in JSDoc:

Keeping JSDoc support up to date with typescript features is a big maintenance burden to ask of the team, and tbh any jsdoc syntax that allows the above is going to be non-standard anyway.

The d.ts concerns that nojvek raise are huge in my experiences as well - current situation is even if I painstakingly write jsdoc to give me full type checking for my project, I can't type it for external users without hand-writing and hand-maintaining a d.ts file anyway; this is ridiculous.

joeytwiddle commented 5 years ago

I have a suggestion. How about allowing definitions in comments, but only complete statements matching the format of a d.ts file? In other words, we intersperse the d.ts file in our JS file.

/* @ts
interface Person {
    firstName: string;
    lastName: string;
}
*/

// @ts function greeter(person: Person): string;
function greeter(person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

Advantages:

Disadvantages:

I also suggest using @ts instead of :: to avoid any flow/typescript ambiguity. We should not use the same marker if we are not compatible with their format.


Edit: To clarify, my suggestion is essentially like pardonmyenglish's proposal except we do not allow inline comments like function greeter(person/*: Person*/), because those are more difficult to parse. Only complete TypeScript statements, in separate comments, would be accepted.

Thus an independent implementation could simply extract all these comments, dump them into a .d.ts file, and they should work without any changes.

pardonmyenglish commented 5 years ago

@joeytwiddle that was already proposed in this issue itself e.g. https://github.com/Microsoft/TypeScript/issues/9694#issuecomment-272664643

nojvek commented 5 years ago

Yeah the hardest part is really convincing Typescript team (cc @DanielRosenwasser) that this is a good idea. TS is essentially a superset of JS, so technically this should be quite straightforward to implement it such that the superset-ness of TS is literally just comments in a JS file.

maranomynet commented 5 years ago

The inability to gradually introduce proper TypeScript annotations into existing JavaScript modules without having to add a compile step for each and every one, is pretty much the only thing holding me and my team back from switching from Flow to TypeScript.

A comment-based annotation option (in .js files flagged with // @ts-check) also dramatically lowers the threshold for developers to do "drive-by-guerrilla-typing" on older projects and smaller modules.

TomasHubelbauer commented 5 years ago

The support for allowJs+checkJs with JSDoc has gotten me personally quite far with type checking in JavaScript files, which is why I personally am interested in this feature.

However, a big, big, drawback of using JSDoc is that it differs from TypeScript too much. There are a lot of patterns (especially dealing with generics, overloads, inference etc.) which I know how to type in TypeScript very well, but can't for the life of me figure out in JSDoc.

On top of that, the JSDoc documentation is very poor and overall it is just a different type system, so you don't really get TypeScript, just a super basic version of it.

This is why I'd like to see actual TypeScript type annotations supported in JavaScript files. I don't know if there is "philosophical" opposition to this from the TypeScript developers or it is just not seen as high-enough value, so the only thing I can do is to chime in and say I'd use it - a lot.

kdmadej commented 5 years ago

I just found myself in a similar situation as @TomasHubelbauer did.

I need to use more advanced concepts like mapped types or conditional types but I can't figure out a way to define the aforementioned concepts using JSDoc.

I'm currently working on a project that doesn't use TS but I'd love to get some type checking in VSCode based on type annotations in comments. Adding support for type annotations in comments would be a life-saver for people who would like to get the benefits of TS but the decision about the techs used in the project is not made by them.

DanielRosenwasser commented 5 years ago

For situations where you need a more advanced type that isn't supported in JSDoc, you can declare the types in a .d.ts file and then reference the types back in the JSDoc.

luciotato commented 3 years ago

For anyone coming here looking to add TypeScript type-annotations within comments, I've made a fork with a hack to allow exactly that: https://github.com/luciotato/plus-typescript/blob/master/README.md https://github.com/luciotato/plus-typescript @kdmadej @TomasHubelbauer @maranomynet @nojvek @joeytwiddle Maintainers are welcomed

nojvek commented 3 years ago

Holy moly. This is incredibly cool @luciotato . What I love about this is it supports full breadth of TS syntax. The current jsdoc annotations that typescript team recommends is really a hodge podge of quirks. I've invested 6 months of my life converting our existing js to jsdoc only to realize there are so many little things missing.

martinheidegger commented 3 years ago

@DanielRosenwasser

For situations where you need a more advanced type...

This is about 2 minutes into trying to define types. I basically have no code that does not use Generics... It becomes a really expensive problem once you realize that 50% of the code needs to be in the .d.ts file. Not only that, but trying to memorize two different syntax is not good for productivity.

ixis-doug commented 2 years ago

Like others who joined late to the party, let me start by saying how much I appreciate the effort that's gone into Typescript. It's an incredible tool, and to be commenting at all on an issue is a testament to that.

The nearly 6 years this issue has been open is a bit discouraging. The use cases and value have been established, @luciotato built a working prototype, and Flow has long supported this, so there are real users of this feature in the wild. Part of what "opt-in types" ought to mean is that you can start using types in a project that's not ready to be converted to Typescript, even if that conversion is rightly considered easy. The value of writing new libraries in TS is limited by the inability to fully exploit the value of those types in vanilla JS consuming code (and I say "fully exploit" to deliberately cover what one cannot accomplish by telling the editor to treat JS files like typescript and other ways of seeing the types of 3rd party libraries in a vacuum, without defining types in the vanilla JS calling code).

joeytwiddle commented 2 years ago

There appears to be some movement in the form of:

https://devblogs.microsoft.com/typescript/a-proposal-for-type-syntax-in-javascript/

... which proposes to redefine what is a comment in future ES.

ixis-doug commented 2 years ago

There appears to be some movement in the form of:

https://devblogs.microsoft.com/typescript/a-proposal-for-type-syntax-in-javascript/

... which proposes to redefine what is a comment in future ES.

This is indeed related and very exciting, but considering there are browsers that haven't hit EOL that don't even support ES2015 (looking at you IE 11), I think this is a potential solution for 2030 javascript/typescript developers, not 2022 javascript/typescript developers. The typescript language being able to find meaning within comments would be a much more powerful solution when backwards compatibility requirements are considered.

maranomynet commented 2 years ago

Also: "We decided to lobby for TypeScript officially becoming JavaScript, but still pretend that's not what we're doing"

🤪

DanielRosenwasser commented 2 years ago

but considering there are browsers that haven't hit EOL that don't even support ES2015 (looking at you IE 11) I think this is a potential solution for 2030

Types can always be stripped away/"downleveled" for older browsers. Considering the proposal will take years of work if it does proceed, 2030 might be when you actually get the feature!