Open nojvek opened 8 years ago
@DanielRosenwasser
Types can always be stripped away/"downleveled" for older browsers.
Stated differently, could we say "well you could still run your code through a typescript compiler to strip the types"? If so, this leaves us in the in the same position we're currently in, no?
I think one of the use case is: Develop with your fancy new browser and develop faster without compile. But in production you still use the transpiled/stripped/minified output even for some ie8 if you like/must.
Well if you're targeting Node, Deno, or primarily evergreen browsers, you can run as-is (especially for the development-time scenarios that @HolgerJeromin just mentioned). If you really need to accommodate older runtimes, you can add this as a production-time build step.
By the way, I have tried using JSDoc in a project, and I learned something I didn't know before:
We don't have to stick to the JSDoc way of declaring types, which usually involves lots of @
tags, and splitting up of objects.
We can instead use TypeScript types inside the JSDocs, to keep things small and familiar!
Here is an example with a function that accepts two strings, and returns an object whose two properties are dictionaries.
/**
* @typedef {Object} MemberGroupsResponse
* @property {Object.<string, MemberGroup>} memberGroups
* @property {Object.<string, Array.<string>>} memberGroupsByUser
*
* @function getMemberGroupsUncached
* @async
* @param {string} month
* @param {string} memberGroupsSheet
* @returns {Promise.<MemberGroupsResponse>}
*/
async function getMemberGroupsUncached(month, memberGroupsSheet) { /* ... */ }
/**
* @type {(month: string, memberGroupSheet: string) => Promise<{
* memberGroups: Record<string, MemberGroup>;
* memberGroupsByUser: Record<string, string[]>;
* }>}
*/
async function getMemberGroupsUncached(month, memberGroupsSheet) { /* ... */ }
Advantage:
We can also put comments like /** @type string | number */
above a variable
Disadvantages:
So if you don't need traditional JSDoc but you would like some TS-checking in your JavaScript files, this hybrid approach might work for you.
(I am using TypeScript type checking in VSCode, with the option js/ts.implicitProjectConfig.checkJs
but // @ts-check
would also work.)
I'm trying to use tsc
to generate .d.ts
files for my fork of a JavaScript project, making minimal changes to the original .js
files. For almost everything tsc
's inference is good enough, and for most of the rest adding comments as described by @joeytwiddle fills in the gaps. But here's one that fails:
The original code:
delete Number.prototype.then;
Types that work in TypeScript:
interface MaybeThenable { then?: Function }
delete (Number.prototype as Number & MaybeThenable).then;
The same types in JSDoc annotation in a .js
file:
/** @typedef { { then?: Function } } MaybeThenable */
/** @type { Number & MaybeThenable } */
var klass = Number.prototype;
delete klass.then;
Is rejected by tsc
:
Type 'Number' is not assignable to type '{ then?: Function; } & number'.
Type 'Number' is not assignable to type 'number'.
'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
73 var klass = Number.prototype;
~~~~~
It seems that tsc
doesn't respect wrapper types given in TSDoc annotations
Turns out it works if I go to constructors, but it would be better if tsc
handled types the same way in both TypeScript annotations and JSDoc annotations
/** @typedef { { prototype: Object & { then?: Function } } } MaybeThenableConstructor */
/** @type { NumberConstructor & MaybeThenableConstructor } */
var konstructor = Number
delete konstructor.prototype.then;
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.
i.e
/: [type] */ /:: [tscode] */