Skip to content

typecheck tests and bump typescript-eslint #2674

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

Merged
merged 52 commits into from
May 28, 2025
Merged

typecheck tests and bump typescript-eslint #2674

merged 52 commits into from
May 28, 2025

Conversation

turadg
Copy link
Member

@turadg turadg commented Dec 30, 2024

evergreen

Description

The typescript-eslint dep was behind so I tried to bump it. The major version breaking change required linted files to be included in a tsconfig. Files in demo, scripts and test were linted but not typechecked, so I added those to the tsconfigs. Then I did a bunch of work to get them to green.

I tried to commit incrementally and mostly stick to one package per commit. There are no stacked changes so you could review by file in HEAD and not miss anything.

Security Considerations

none

Scaling Considerations

none

Documentation Considerations

none

Testing Considerations

CI

Compatibility Considerations

Some slight changes to type interfaces but no breaking runtime changes

Upgrade Considerations

Update NEWS.md for user-facing changes.
? necessary?

@turadg turadg mentioned this pull request Jan 3, 2025
Copy link
Member

@boneskull boneskull Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe exclude this dir from typechecking? same with other frequent @ts-nocheck directives

@@ -9,6 +9,7 @@ import bundleSource from '../src/index.js';
* @param {string} entry
* @param {Options} options
*/
// @ts-expect-error 'Options' could be instantiated with a different subtype of constraint 'Partial<any>'.
const generate = async (entry, options = {}) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const generate = async (entry, options = {}) => {
const generate = async (entry, options) => {

This should suppress the error, but then you'll need to supply an empty object somewhere below

@@ -11,6 +11,7 @@ test('no-transforms applies no transforms', async t => {
const entryPath = url.fileURLToPath(
new URL(`../demo/circular/a.js`, import.meta.url),
);
// @ts-expect-error Property 'endoZipBase64' does not exist on type '{ moduleFormat: "endoScript"; source: string; } | { moduleFormat: "endoZipBase64"; endoZipBase64: string; endoZipBase64Sha512: string; } | { moduleFormat: "nestedEvaluate"; source: string; sourceMap: string; } | { ...; }'.
Copy link
Member

@boneskull boneskull Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like we'll need to use @overload to define bundleSource

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 we already do, and specifically that passing moduleFormat: 'endoZipBase64' is supposed to obviate this check. The template for bundleSource is supposed to infer which overload is called based on that option and narrow the return type.

@@ -11,6 +11,7 @@ test('test objectMetaMap', async t => {
? undefined
: {
...desc,
// @ts-expect-error desc.value possibly undefined
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably throw a t.assert.ok(desc.value) before this statement

Copy link
Member

@boneskull boneskull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

many comments and questions but nothing blockworthy

@@ -19,6 +19,7 @@ export const parseJsonp = (bytes, _specifier, _location, _packageLocation) => {
const compartment = new Compartment({
__options__: true,
globals: harden({
// @ts-expect-error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like we should enable the rule that requires an explanation for use of @ts-expect-error

@@ -11,6 +11,7 @@ const fixture = new URL(
import.meta.url,
).toString();

// @ts-expect-error XXX Node interface munging
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted this to actually work. 😄

  • @boneskull investigate why this is causing an error

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when I rebased on master it seems to work

@@ -88,7 +89,7 @@ export function scaffold(
assertFixture,
fixtureAssertionCount,
{
onError,
onError = /** @type {(t, {error, title})} */ (undefined),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo this should be a @ts-expect-error instead of this thing that is plainly untrue 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. I made it accurate instead

@@ -37,7 +37,8 @@ export const make = () => {
};

/**
* @type {NameHub['write']}
* @param {string[]} petNamePath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was wrong with NameHub? do we still need that type?

'@typescript-eslint/restrict-plus-operands': 'warn',
// XXX override for RESM concession below
'@endo/no-optional-chaining': 'off',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait, I thought this rule was actually needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "RESM concession below" is:

    // Agoric still uses Endo dependencies under an emulation of ESM we call RESM
    // because it is invoked with `node -r esm`.
    // RESM does not support ?? nor ?. operators, so we must avoid them expressly.

Endo tests are not exported so optional-chaining is fine in tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@boneskull we have very recently been liberated from this constraint. Thanks for spotting.

@@ -122,7 +122,9 @@ test('packages in-the-wild', t => {

function testContent6() {
const list = [];
list.push = function newPush() {};
list.push = function newPush(...args) {
return args.length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -16,7 +16,9 @@ test('lockdown start Date is powerful', t => {
});

test('lockdown Date.prototype.constructor is powerless', t => {
const SharedDate = Date.prototype.constructor;
const SharedDate = /** @type {DateConstructor} */ (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Date not Date.prototype.constructor? cc @erights

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, SharedDate is attenuated to avoid a timing side-channel by default, as is Date.now() and similarly Math.random() for a deterministic PRNG snooping side-channel. The signature is the same.

@@ -2,12 +2,15 @@
"extends": "../../tsconfig.eslint-base.json",
"compilerOptions": {
"allowJs": true,
"skipLibCheck": true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skipLibCheck: false probably also why linting is slow

@@ -135,10 +135,12 @@ export type ModuleMapHook = (
moduleSpecifier: string,
) => ModuleDescriptor | undefined;
export type ImportHook = (moduleSpecifier: string) => Promise<ModuleDescriptor>;
export type ImportNowHook = (moduleSpecifier: string) => ModuleDescriptor;
export type ImportNowHook = (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this true? Can it return undefined?

@@ -19,6 +19,7 @@ test('zip round trip', async t => {

const reader = new ZipReader(writer.snapshot());
const text = textDecoder.decode(reader.read('hello/hello.txt'));
// @ts-expect-error undefined if file not found
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would probably assert the result is truthy instead

@turadg turadg enabled auto-merge May 28, 2025 18:08
Copy link
Member

@kriskowal kriskowal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is largely mechanical and I don’t want a big diff like this to stay on the lam for long. Please at least address the runtime behavior regression in RUNME.js with a type exception for now. Filed #2834.

@@ -11,6 +11,7 @@ test('no-transforms applies no transforms', async t => {
const entryPath = url.fileURLToPath(
new URL(`../demo/circular/a.js`, import.meta.url),
);
// @ts-expect-error Property 'endoZipBase64' does not exist on type '{ moduleFormat: "endoScript"; source: string; } | { moduleFormat: "endoZipBase64"; endoZipBase64: string; endoZipBase64Sha512: string; } | { moduleFormat: "nestedEvaluate"; source: string; sourceMap: string; } | { ...; }'.
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 we already do, and specifically that passing moduleFormat: 'endoZipBase64' is supposed to obviate this check. The template for bundleSource is supposed to infer which overload is called based on that option and narrow the return type.

import { Fail } from '@endo/errors';
import { makeGuest, makeHost } from './traplib.js';

if (!maybeParentPort) throw new Error('null parentPort');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess but do not know that this is safe in the face of port 0 as opposed to undefined. 0 is a special port for listen, but connect won’t ever provide an address with a port of 0 unless there’s an error.

@@ -1,3 +1,4 @@
// @ts-nocheck
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can no longer be inferred from directory pattern matching? I do like that they’re evident, but also they are numerous.

Comment on lines +55 to +58
* @param {string} defaultSetting
* @param {string[]} [optOtherValues]
* If provided, the option value must be included or match `defaultSetting`.
* @returns {T}
* @returns {string}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t recall why this was a template type before, but there was probably a reason, @erights?

'@typescript-eslint/restrict-plus-operands': 'warn',
// XXX override for RESM concession below
'@endo/no-optional-chaining': 'off',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@boneskull we have very recently been liberated from this constraint. Thanks for spotting.

@@ -42,7 +42,7 @@ test('test defineExoClass', t => {
t.throws(() => upCounter.incr(-3), {
message: 'In "incr" method of (UpCounter): arg 0?: -3 - Must be >= 0',
});
// @ts-expect-error bad arg
// FIXME typedef should catch bad arg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attn @erights, I think we can tolerate a regression in tsc catching a case here. Maybe we can downgrade FIXME to a note that we would not be surprised if ts-expect-error became necessary in a future tsc upgrade.

const bundle = await bundleSource(start, {
cacheSourceMaps: true,
});
const bundle = await bundleSource(start, {});
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 the purposes of this file is to validate that source maps get cached. Let’s keep the code correct at runtime and mark the error as expected, maybe file an issue to fix the signature of bundleSource.

@@ -1,3 +1,4 @@
/* global globalThis */
export const NativeModuleSource = globalThis.ModuleSource;
// @ts-expect-error XXX typedef
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not in this case. I don’t think we have an analogous /// <reference type="@endo/module-source/shim.js"> but perhaps we should.

@@ -1,8 +1,10 @@
export const mockHardened = new WeakSet();
/** @type {import("../types.js").Harden & {isFake?: true}} */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d like to converge on this preference opportunistically. It is not a requirement for this change.

@@ -16,7 +16,9 @@ test('lockdown start Date is powerful', t => {
});

test('lockdown Date.prototype.constructor is powerless', t => {
const SharedDate = Date.prototype.constructor;
const SharedDate = /** @type {DateConstructor} */ (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, SharedDate is attenuated to avoid a timing side-channel by default, as is Date.now() and similarly Math.random() for a deterministic PRNG snooping side-channel. The signature is the same.

turadg added 23 commits May 28, 2025 13:12
hack around,

/opt/agoric/endo/packages/bundle-source/demo/reexport-fortune-ts.js
  0:0  error  Parsing error: /opt/agoric/endo/packages/bundle-source/demo/reexport-fortune-ts.js was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject

/opt/agoric/endo/packages/bundle-source/demo/reexport-meaning-js.js
  0:0  error  Parsing error: /opt/agoric/endo/packages/bundle-source/demo/reexport-meaning-js.js was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject
Work around:

dist/types.d.cts:558:16 - error TS2300: Duplicate identifier 'Compartment'.

558   export class Compartment {
                   ~~~~~~~~~~~

  types.d.ts:559:16
    559   export class Compartment {
                       ~~~~~~~~~~~
    'Compartment' was also declared here.
Without this building exported.js fails because it would overwrite the exported.d.ts in scm
imports packages that aren't strict

Found 76 errors in 10 files.

Errors  Files
     6  ../env-options/src/env-options.js:17
     2  ../eventual-send/shim.js:4
    28  ../eventual-send/src/handled-promise.js:142
     8  ../eventual-send/src/local.js:8
     3  ../eventual-send/src/message-breakpoints.js:133
     4  ../eventual-send/src/postponed.js:18
     9  ../eventual-send/src/track-turns.js:20
     1  ../init/pre-remoting.js:5
     1  ../lockdown/post.js:12
    14  ../ses-ava/src/ses-ava-test.js:33
turadg added 3 commits May 28, 2025 13:41
@turadg turadg merged commit 26df345 into master May 28, 2025
15 of 16 checks passed
@turadg turadg deleted the ta/lint-bump branch May 28, 2025 21:01
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