-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Several improvements to typings #8884
Several improvements to typings #8884
Conversation
Thank you so much for the pull request @thw0rted! I noticed this is your first pull request and I wanted to say welcome to the Cesium community! The Pull Request Guidelines is a handy reference for making sure your PR gets accepted quickly, so make sure to skim that.
Reviewers, don't forget to make sure that:
|
I thought I'd done the CLA before but I probably forgot. (There was a whole thing about 2 years ago about having my company sign since I'm doing the work on the clock, but I finally got cleared by Legal to just sign the individual one instead.) It's done now. |
This new commit converts |
Yeah, I definitely thought you were a contributor already as well, either way thanks for the PR. I'm going to review now and would love to get this into Monday's release so that TS starts with it's best foot forward. |
Why? I'm not a fan of |
Can confirm we've received your individual CLA @thw0rted . |
Sounds good to me, I verified that the npm scripts in VS Code picks everything up. |
re: npx, maybe it's something I did wrong with Gulp? When I ran it, it would error that it couldn't find I made the change because |
Thanks, just to debug further, were you running |
ETA: honest question, I don't know if |
@thw0rted I believe npx ships with node/npm these days. I'll confirm of course. I was asking mainly so I could reproduce on my end. Also, we have other parts of gulpfile where we do the same thing so ultimately we should make them consistent. Assuming npx is always available, I'm not going to bikeshed it any further and will just look into it as a followup PR. Thanks. |
Source/Core/Resource.js
Outdated
* Initialization options for the Resource constructor | ||
* | ||
* @property {String} url The url of the resource. | ||
* @property {Resource.QueryParameters} [queryParameters] An object containing query parameters that will be sent when retrieving the resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great point. Since this is a type alias, basically for Object<string, string|num|bool|(string|num|bool)[]|undefined>
, there's really nothing to print in the template. I should have put some text description in there, at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and added a one-liner so it's not blank, at least. If you want to flesh it out feel free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's going to be really confusing for non TS users reading the doc to understand what they are supposed to pass here. What is the fundamental issue you are trying to prevent here, people passing an object that has more than just primitive values? Technically users can pass anything that has a toString
function, right? So wouldn't Object
still be the best option here no matter what?
Source/Core/Event.js
Outdated
@@ -46,7 +47,7 @@ Object.defineProperties(Event.prototype, { | |||
* An optional scope can be provided to serve as the <code>this</code> pointer | |||
* in which the function will execute. | |||
* | |||
* @param {Function} listener The function to be executed when the event is raised. | |||
* @param {Listener} listener The function to be executed when the event is raised. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ends up creating a non-existent Listener
entry in the doc:
I started to dig into template/generics a little on the JSDoc and I agree they don't appear to work at first glance. I'll see what I can find. I want to be careful about trying to do too much too fast since we want to use generics in more places (like Property) but I don't want to get too crazy with workaround either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally forgot to link you to englercj/tsd-jsdoc#134 -- it looks like @template
is flat-out broken, but also there isn't consensus about how to provide a default value for a type parameter. Sadly that probably means the ugly hack in the gulpfile will be required for the foreseeable future if you're going to use generics.
@@ -429,7 +427,6 @@ CesiumMath.DEGREES_PER_RADIAN = 180.0 / Math.PI; | |||
* | |||
* @type {Number} | |||
* @constant | |||
* @default {@link CesiumMath.RADIANS_PER_DEGREE} / 3600.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm okay with these changes, but it made me realize there's a bug with Math/CesiumMath in my PR, so thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not positive this would work even without the Math error, because I can't find anything saying that an expression (not a literal) for @default
is supposed to be supported.
Source/DataSources/DataSource.js
Outdated
*/ | ||
errorEvent: { | ||
get: DeveloperError.throwInstantiationError, | ||
}, | ||
/** | ||
* Gets an event that will be raised when the value of isLoading changes. | ||
* @memberof DataSource.prototype | ||
* @type {Event} | ||
* @type {Event<function(this, boolean)>} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was worried about how JSDoc would handle this, but I think this is okay, assuming we can get Event as a template working a little better.:
However, I'm pretty sure this breaks duct typing because CustomDataSource/CzmlDataSource/KmlDataSource/GeoJsonDataSource don't have the same signatures.
I'm not sure if the best course of action is to update the signatures, or pull out the Event related changes in a separate PR for more discussion. I'll finish up the rest of the review and think about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I have lines like
let src: DataSource;
...
src = new KmlDataSource(...)
in my code and it didn't break when compiling against this branch's typings. I can see where you'd be concerned, though, so I understand if you want to hold off. (If there's no rush, I could always fix all uses of Event on Monday, it's not actually that many.)
Source/DataSources/Entity.js
Outdated
* @property {Boolean} [show] A boolean value indicating if the entity and its children are displayed. | ||
* @property {Property | string} [description] A string Property specifying an HTML description for this entity. | ||
* @property {PositionProperty | CallbackProperty | Cartesian3} [position] A Property specifying the entity position. | ||
* **** TODO **** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are these TODOs for? Also, CallbackProperty is officially supported here. The object needs to conform to the PositionProperty signature to work in all cases. Please write up a separate issue so that we can either add a CallbackPositionProperty or something similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it's asking about the type of orientation
and viewFrom
. Are they Matrix4
? Cartesian3
? The docs aren't much help, as they just use the term to define itself ("Gets or sets the orientation" -- gee, thanks :D )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re CallbackProperty, was that isn't officially supported? I've been using it for a while but if that's wrong, we can remove it from the typing here and I'll just any-cast and cross my fingers until official support gets added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
viewFrom
is a Cartesian3
. Orientation
is a Quaternion
There are places where we call PositionProperty.getValueInReferenceFrame
, such as path visualization and exportKml. So CallbackProperty
is technically incorrect for now. Turns out we have an issue for this already: #5534 so let's revert for now and maybe we can fix for 1.71.
Source/DataSources/EntityCluster.js
Outdated
@@ -963,7 +963,8 @@ EntityCluster.prototype.destroy = function () { | |||
* @callback EntityCluster.newClusterCallback | |||
* | |||
* @param {Entity[]} clusteredEntities An array of the entities contained in the cluster. | |||
* @param {Object} cluster An object containing billboard, label, and point properties. The values are the same as | |||
* @param {{billboard: Billboard, label: Label, point: PointPrimitive}} cluster An object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the intent here but this just ends up being an any
in the type definition either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I totally didn't notice that. Was I right about the actual shape of the object? I can fix it to use the correct @param
syntax, I'm just spoiled by the shorthand TS lets you use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the shape is correct.
* @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to draw the polyline. | ||
* @property {MaterialProperty | Color} [depthFailMaterial] A property specifying the material used to draw the polyline when it is below the terrain. | ||
* | ||
* **** TODO **** this was originally only ArcType, not a Property (!) -- pretty sure that was wrong? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it's definitely a Property in the code, so you can remove this todo and keep your change. Thanks!
Source/DataSources/PropertyBag.js
Outdated
* | ||
* @param {Object} [value] An object, containing key-value mapping of property names to properties. | ||
* @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property. | ||
* @typedef {PropertyBagType} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks JSDoc HTML output completely.
Source/DataSources/exportKml.js
Outdated
@@ -221,6 +221,33 @@ IdManager.prototype.get = function (id) { | |||
|
|||
return id.toString() + "-" + ++ids[id]; | |||
}; | |||
/** | |||
* @variation 2 KML return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes in this file break exportKml JSDoc output completely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well this is weird. The version I'm looking at right now is not what I committed. I saw that there's some kind of commit hook to run a prettifier -- could that be the culprit? It's important to have
/**
* Body of documentation
*
* @variation 1
* @param ...
* @example (for variation 1)
*//**
* @variation 2
* @param ...
* @example (for variation 2)
*/
Exactly thus, with no spaces between the closing tag for the first block and the opening tag for the second. That's part of the JSDoc spec, apparently, though ironically documentation about the spec is a bit dodgy in my experience. Is it possible to exempt a section or a whole file from being "massaged" by the prettifier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would rather stick with the union return for now. This type of decision may affect the API elsewhere and our main goal is keeping the API consistent. I would just revert the file for now. Feel free to open a separate PR for further discussion.
@@ -128,8 +128,8 @@ function configureCameraFrustum(widget) { | |||
* @param {Clock} [options.clock=new Clock()] The clock to use to control current time. | |||
* @param {ImageryProvider} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to <code>false</code>, no imagery provider will be added. | |||
* @param {TerrainProvider} [options.terrainProvider=new EllipsoidTerrainProvider] The terrain provider. | |||
* @param {SkyBox} [options.skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. | |||
* @param {SkyAtmosphere} [options.skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to <code>false</code> to turn it off. | |||
* @param {SkyBox| false} [options.skyBox] The skybox used to render the stars. When <code>undefined</code>, the default stars are used. If set to <code>false</code>, no skyBox, Sun, or Moon will be added. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're changing this here, we should change it for the other params in this signature as well, such as ImageryProvider
@thw0rted thanks again for the PR! The Entity and GraphicsXXX changes are all fine with me. The ImageryProvider changes are okay as well, but we really should do them all for consistency. Some are still using the "old" documentation strategy, such as The main thing stopping me from merging this is the broken JSDoc and Event and PropertyBag changes. I would recommend backing them out and opening a separate PR. I don't care about cleaning up the commit history, so this should be trivial to do. We may still be able to get them in 1.70, I just want to get as much as we can into the primary PR ASAP. Since we want to get this into 1.70, I'm also okay with taking this PR over if you are unable to work on it until Monday. Just let me know. Thanks again, now you'll go down in history as the first community member to contribute to our official TS definitions! |
Please go ahead and back out the things you're not comfortable with. It's quittin' time here in Europe for today, and while I might put in a few hours over the weekend, I don't want to commit to it ahead of time or hold up your release. |
Thanks @thw0rted. I'm not sure why I thought you were in the states, enjoy your weekend. |
Thanks @thw0rted! I submitted some clean-up and backed out some changes that we need to think about more, but I parked them on a branch, |
Note up front, I had to change the command in the gulpfile from a relative path to
npx
. I think this is more or less universally supported now across platforms but I haven't researched it fully.The biggest change (by volume, certainly) is moving a lot of options-argument definitions out into named interfaces with
@typedef
. Most of these are calledClassName.ConstructorOptions
, with a couple of.LoadOptions
for DataSources that have common options for aload
method.One or two commits are dedicated to converting
Event
to take a generic parameter specifying the callback signature. This lets you type events as e.g.Event<Function(int, bool)>
, which means that inviewer.fooEvent.addEventListener((num, flag) => { .... })
, the arguments are typed correctly. I only added types for the few events that I personally use but I could pretty easily fix the rest of them if you like this approach.@template
to work very well so I wound up adding a hack to the gulpfile. I'm going to try to find a few minutes today to put together a tiny repro and open an issue withtsd-jsdoc
to see if I am missing something. It's also possible that there just isn't any support for generic parameter defaults (Event<Listener extends Function = Function>
), which is super important in this case, which would probably mean keeping the hack in place anyway.The
Resource
class got a couple@typedef
s that more precisely define what kind of object can be used as aqueryParameter
.A couple of the changes are just for correctness -- arguments or properties that are allowed to be
undefined
orfalse
, etc.Unanswered questions are marked with
*** TODO ***
: a couple of properties whose shapes aren't fully documented on Entity, and one option for PolylineGraphics that can probably be a Property but I wanted to double check before making the change.Entity
PolylineGraphics#ArcType
can be aProperty
PS: I just noticed that I accidentally committed deleting
.vscode/tasks.json
, but the good news is that actually everybody should do that, because the tasks that were previously in there should now be picked up automatically via NPM integration, unless for some reason you're stuck on a year-plus-old build of VSCode.