Skip to content
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

Merged
merged 8 commits into from
Dec 20, 2024
Merged

Conversation

martinpitt
Copy link
Member

@martinpitt martinpitt commented Dec 19, 2024

This reduces the ignore list by 8, some low-hanging fruit and quite useful! (it found little bugs)

@martinpitt martinpitt added the blocked Don't land until something else happens first (see task list) label Dec 19, 2024
@martinpitt
Copy link
Member Author

I'll rebase this after #21454, to clean up metrics.jsx in a nicer way.

@martinpitt martinpitt added the no-test For doc/workflow changes, or experiments which don't need a full CI run, label Dec 19, 2024
`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.
@martinpitt martinpitt removed blocked Don't land until something else happens first (see task list) no-test For doc/workflow changes, or experiments which don't need a full CI run, labels Dec 19, 2024
@martinpitt martinpitt requested a review from mvollmer December 19, 2024 15:08
Copy link
Member

@mvollmer mvollmer left a 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.

@@ -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.
Copy link
Member

@mvollmer mvollmer Dec 20, 2024

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.

Copy link
Member Author

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.
Copy link
Member

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.

Copy link
Member Author

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));
Copy link
Contributor

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.

Comment on lines +1556 to +1559
self.wait = function(func) {
if (func)
waits.always(func);
return waits;
Copy link
Contributor

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]: [] });
Copy link
Contributor

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.

Comment on lines +796 to +798
setFilters({
activeState: [],
fileState: []
Copy link
Contributor

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.

Copy link
Member

@mvollmer mvollmer left a 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.

@mvollmer mvollmer merged commit c3f9c47 into cockpit-project:main Dec 20, 2024
86 of 87 checks passed
@martinpitt martinpitt deleted the types branch December 20, 2024 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants