-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Proposal] Provide TS type checking based on JSDoc annotations #1415
Comments
I would love to see this working with CKE5 code. For me I see problems with:
which implies this (AFAICS):
So it means that instead of:
Also is sad :( |
No, it means that instead of
For the usage of For methods and properties, all work for defined ones, but it's harder to use them with not defined. E.g. in this scenario there's no need for anything extra: class A {
constructor() {
this.b = new B();
}
someMethod() {
}
} But the following won't work. class A {
constructor() {
/**
* @member {String} prop
*/
this.set( 'prop', 0 );
}
} It'd need to be changed to at least something like this: class A {
constructor() {
/**
* @type {String}
*/
this.prop;
this.set( 'prop', 0 );
}
} |
|
I didn't make it clear, but the TS team still works actively on the support for JSDoc: https://github.com/Microsoft/TypeScript/issues?q=is%3Aopen+is%3Aissue+label%3A%22Domain%3A+JSDoc%22 |
I think that since our code is already statically typed and considering the number of effort we put to describe all parameters in docs the most complicated part of the work is already done. Not using TypeScript at this point would we a huge waste of the potencial. The only question is when we will have time to work on it. |
We recently found a bug which would be noticed automatically by TS: https://github.com/ckeditor/ckeditor5-engine/pull/1613/files/6c630fd38a634cd46c9433a896606cb814f719b0#r242981678 |
I've been asked about my thoughts so... It looks extremely promising. Migrating our source code to TS doesn't seem to be a good option (see this thread – https://twitter.com/reinmarpl/status/1082199078463782912), but a lighter integration with TS makes much more sense. We'll be type safe, future safe and inclusive. |
Probably the most sane thing to do now :) Looking forward to it. |
I've started to work on some solution to the mixins problem but I've hit that issue - microsoft/TypeScript#18732 The idea of mixins was pretty promising though as mixins could be a part of the inheritance system which TS can understand - http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/. The corresponding TS code would look like this: type Constructor<T> = new (...args: any[]) => T;
function Mixin1<T extends Constructor<{}>>(SuperClass: T = class {}) {
return class extends SuperClass {
foo() {}
};
}
function Mixin2<T extends Constructor<{}>>(SuperClass: T = class {}) {
return class extends SuperClass {
bar() {}
};
}
class C extends Mixin1(Mixin2()) {
baz() {
this.foo();
this.bar();
}
} In short, the problem in the JS + JSDoc code is that JSDoc template types can't be narrowed, while TS requires to know here that a type is a constructor type. |
The question is how often we do have 2 mixins for a single class. All I can find is |
|
The number of such problems isn't big, but that number can grow at any time. This is a list of files that use mixins and inheritance or many mixins at the same time Observable plugins:
Emittable classes that inherit over basic classes:
Editors that mix DataApiMixin, ElementApiMixin? and inherit over the base Editor class:
Others:
Yep, for now, the only way to check that a class |
To sum up the needed work to migrate the code and fix some problems, I'm creating a list of tasks needed to align our codebase and tools for this change:
Notes:JSDocJSDoc could be a big problem here. I've been trying to add some hooks so the parser, so the special type references (like The potential solutions:
TS configurationThe configuration could be stored in each package, so it will be easy to test it on CI. This will also improve the experience for anyone using TS supporting IDE) The {
"compilerOptions": {
"allowJs": true,
"noEmit": true,
"checkJs": true,
"target": "es6"
},
"include": [
"src/**/*.js"
]
} Potential blockers:
I'll be updating the above list. |
The summary - pros, cons, and blockersCons, blockers:
Pros:
|
Recently a guide for creating TS-correct JS code was published on https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html |
looks like the only blocker left is microsoft/TypeScript#7546 ?but there is a pre-packed version for that microsoft/TypeScript#32372 (comment) |
Hi @isubasti, the real blocker is the huge amount of lines to rewrite (plus possible blockers that weren't caught yet) that requires dozens (or hundreds?) of man-days. The codebase constantly grows and this task gets bigger and more complicated with each passing day. |
This works: /**
* @template { new(...args) => {} } T
* @param {T} Super
*/
const Mixin = Super => class extends Super {
mixinMethod() { }
} |
Yep, it works now thanks to the generic narrowing in the |
With the 3.8 release TS will understand Ref: https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/, the JSDoc Property Modifiers section. |
@ma2ciek I've just found this approach to mixin (intersection type). Would it solve some issues? Without much digging into it it looks that intersection type follow what we do while using mixins - adding some methods/properties to type. The |
This would work if we would export something like I also guess that in our case it's not an intersection type, but the type can be somehow computed dynamically using some TS advanced types. The intersection type would work for plain object. In our case we need to mix a class with a class or an object that would ship missing methods. |
I'm closing this ticket in favor of #11704. |
About half a year ago TS started parsing JSDoc comments inside JS, so the JS code can be statically type checked during the development without the need to write in TS. During the last hackathon, I've created a sample based on our codebase showing what can be achieved by introducing such a tool.
Here are some screenshots with examples of what the typed JS is capable of:
A full list of all supported JSDoc tags so far is available here and the list is still growing. For now, the valuable missing ones for us are
@property
and@method
- microsoft/TypeScript#28730,@impements
(there's a workaround),@public
,@protected
and@private
.But there's not going to be all roses. TS doesn't directly support mixins. It supports only inheritance with one base class. This could be somehow workaround, but it would need to be thought through.
How to test it?
tsconfig.json
file in the main repositoryInstall TS locally or globally (
npm install typescript
).To have IDE support, make sure that the typescript plugin is installed in your IDE (VS Code has built-in support).
Try to find if there's a
enforce checkJs option
in your IDEIf the above option isn't possible, try to add
// @ts-check
at the beginning of the file, check if that works for you.tsc
command.I've created a branch for testing that has ~30 errors - https://github.com/ckeditor/ckeditor5-utils/tree/typechecking (mixins on this branch are temporarily removed)
Pros:
tsc
command.lodash
,mocha
.// @ts-check
,//@ts-nocheck
and// @ts-ignore
flags.d.ts
))[https://github.com/Allow--declaration
with--allowJs
microsoft/TypeScript#7546] - it will solve the Typings for TypeScript #504 out of the box.Cons:
module:...
references becomes invalid (so the codebase would need a massivesearch&replace
refactoring).import()
references and relative references that comes from imports to name few.@implements
for classes (there's a workaround),@method
and@property
in classes doesn't work (methods an properties work out of the box if they are provided, so this issue touches only not defined ones).Unknown:
I'm interested in hearing your opinions.
The text was updated successfully, but these errors were encountered: