-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Fix some type errors in JavaScript #21452
Conversation
I'll rebase this after #21454, to clean up metrics.jsx in a nicer way. |
`getFilterLabelKey()` can return `undefined`. Fix onDeleteChipGroup() to not set an undefined filter, same as onDeleteChip. This is the last instance of TS2464 "A computed property name must be of type ...".
Avoid the `delete` operator. We don't define the types explicitly, so tsc complains about > TS2790: The operand of a 'delete' operator must be optional. This was also a bit hard to read -- `binary` is derived from `options.binary`, that code just translates our historic API impedance mismatch between cockpit.js (treating `binary` as a booelan) and the JSON bridge protocol (where `binary` is a string with the only allowed value "raw"). Move this closer together, document it, and write it in a more explicit form.
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.
Thanks! I think I found a nicer fix for the DBusProxies issue.
pkg/lib/cockpit.js
Outdated
@@ -1900,6 +1900,8 @@ function factory() { | |||
if (!options) | |||
options = { }; | |||
ensure_cache(); | |||
// this isn't a real class and only internal API; cockpit.d.ts annotates the return value DBusProxies | |||
// @ts-expect-error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. |
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.
So, I think the fundamental issue is that TypeScript doesn't recognize function DBusProxies
as a constructor. Things like
function Foo(x) {
this.x = x;
}
const f = new Foo();
normally just work.
However, this produces the exact error TS7009:
function Bar(x) {
}
const b = new Bar();
The difference is that Bar
does not assign to this
, and neither does DBusProxies
. It uses Object.defineProperties
, and TS doesn't look inside of that apparently.
The TS7009 error goes away when adding a bogus self.foo = 0
assignment inside DBusProxies
. That is enough to make TS understand that it is a constructor.
I would prefer to do that. I think this will work:
self.client = client;
self.iface = iface;
self.path_namespace = path_namespace;
let waits;
self.wait = function(func) {
if (func)
waits.always(func);
return waits;
}
Object.defineProperties(self, {
client: { enumerable: false, writable: false },
iface: { enumerable: false, writable: false },
path_namespace: { enumerable: false, writable: false },
wait: { enumerable: false, writable: false }
});
That is, we initialize the new object in the normal way, and only use Object.defineProperties to modify the "enumerable" and "writable" attributes of the properties.
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.
Niice, thanks for figuring this out! Reworked accordingly, let's confirm with the bo[ts]s!
@@ -53,7 +53,6 @@ ignored_codes = [ | |||
"TS7005", # Variable '*' implicitly has an 'any[]' type. | |||
"TS7006", # Parameter '*' implicitly has an 'any' type. | |||
"TS7008", # Member '*' implicitly has an 'any[]' type. | |||
"TS7009", # 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. |
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 okay to remove this here as well. The problem is not the implicit "any", but that TS missed that something is a constructor, which is worth fixing even in relaxed code.
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.
Right, with that new approach we can and should fix similar instances
Fix the last remaining instance of > error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. That was because the DBusProxies() function was not considered a class constructor, as it did not assign to `this`. So do that for its properties, and only use `defineProperties()` for declaring their read-onliness. Thanks Marius Vollmer for figuring this out!
We dropped jQuery many years ago. This test is hopelessly outdated. This gets rid of "TS2581: Cannot find name '$'".
cockpit.spawn() never fails with a bare "closed". There are no expected failures there, so just always warn about them.
Don't put the cache onto the function object, that confuses the type checker. Make it an internal global variable instead. Fixes > pkg/systemd/hwinfo.jsx(133,39): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. (There is another instance of this error which the next commit will address).
This function calls itself recursively, so the type checker cannot infer its signature. Add one explicitly. Fixes > pkg/storaged/crypto/keyslots.jsx(405,44): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. which is the last remaining instance of that error. So stop ignoring it.
console.warn(error); | ||
} | ||
}); | ||
.catch(error => console.warn("watch-appstream.py failed:", error)); |
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 added line is not executed by any test.
self.wait = function(func) { | ||
if (func) | ||
waits.always(func); | ||
return waits; |
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.
These 4 added lines are not executed by any test.
@@ -790,7 +790,13 @@ const ServicesPageFilters = ({ | |||
const onDeleteChipGroup = (typeLabel) => { | |||
const type = getFilterLabelKey(typeLabel); | |||
|
|||
setFilters({ ...filters, [type]: [] }); | |||
if (type) | |||
setFilters({ ...filters, [type]: [] }); |
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 added line is not executed by any test.
setFilters({ | ||
activeState: [], | ||
fileState: [] |
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.
These 3 added lines are not executed by any test.
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.
Thanks! Great that it works.
This reduces the ignore list by 8, some low-hanging fruit and quite useful! (it found little bugs)