rest.js icon indicating copy to clipboard operation
rest.js copied to clipboard

TypeScript signature of async iterators changed unexpectedly:

Open bcoe opened this issue 4 years ago • 12 comments

Checklist

  • [x] I checked all open bugs and none of them matched my problem.

Environment

  • [x] https://api.github.com
  • [x] Node.js

Versions

├─┬ @octokit/[email protected]
│ ├─┬ @octokit/[email protected]
│ └─┬ @octokit/[email protected]
│   └── @octokit/[email protected]
├─┬ @octokit/[email protected]
├─┬ @octokit/[email protected]
│ ├─┬ @octokit/[email protected]
│ │ ├─┬ @octokit/[email protected]
│ │ ├─┬ @octokit/[email protected]
│ │ │ ├─┬ @octokit/[email protected]
│ ├── @octokit/[email protected]
│ └─┬ @octokit/[email protected]
├─┬ @probot/[email protected]
├─┬ [email protected]
│ ├─┬ @octokit/[email protected]
│ │ ├─┬ @octokit/[email protected]
│ │ │ ├─┬ @octokit/[email protected]
│ │ ├─┬ @octokit/[email protected]
│ │ │ ├─┬ @octokit/[email protected]
│ │ │ │ ├── @octokit/[email protected]
│ ├─┬ @octokit/[email protected]
│ ├─┬ @octokit/[email protected]
│ ├─┬ @octokit/[email protected]
│ ├─┬ @octokit/[email protected]
│ ├─┬ @octokit/[email protected]

What happened?

In a minor version of one of the octokit dependencies, the method signature of pagination has changed significantly. This was the old code that worked:

    const installationRepositoriesPaginated = octokit.paginate.iterator(
      octokit.apps.listReposAccessibleToInstallation,
      {
        mediaType: {
          previews: ['machine-man'],
        },
      }
    );
    for await (const response of installationRepositoriesPaginated) {
      for (const repo of response.data) {
        yield repo;
      }
    }

When updating to the latest versions of libraries in package-lock.json, compilation fails due to a significantly different type:

src/gcf-utils.ts:651:26 - error TS2488: Type '{ total_count: number; repositories: { id: number; node_id: string; name: string; full_name: string; license: { key: string; name: string; url: string | null; spdx_id: string | null; node_id: string; html_url?: string | undefined; } | null; ... 82 more ...; starred_at?: string | undefined; }[]; repository_selection?...' must have a '[Symbol.iterator]()' method that returns an iterator.

Rather than being an array, data now returns an object with a top level repositories field which is an array.

Minimal test case to reproduce the problem

Renovates routine lock maintenance surfaces issue:

https://github.com/googleapis/repo-automation-bots/pull/2241

What did you expect to happen?

Type to remain similar in a minor or patch update.

What the problem might be

Not sure.

bcoe avatar Jul 07 '21 21:07 bcoe

If you need to iterate through repositories I'd recommend using https://github.com/octokit/app.js/ :) I hope to migrate Probot to it with the next version, but not sure how long that will take.

I'm looking into the type change now

gr2m avatar Jul 08 '21 20:07 gr2m

Hm it looks like it returns both, which is incorrect. But when you do the for ... of loop it gets the types from the array as it should. So far I cannot reproduce the problem locally, but I'm still looking into it.

gr2m avatar Jul 08 '21 21:07 gr2m

I couldn't reproduce the problem with

mkdir test
cd test
npm init -y
npm i @octokit/rest

Then create index.ts

import { Octokit } from "@octokit/rest";
const octokit = new Octokit();

export async function* test() {
  const installationRepositoriesPaginated = octokit.paginate.iterator(
    octokit.apps.listReposAccessibleToInstallation,
    {
      mediaType: {
        previews: ["machine-man"],
      },
    }
  );

  for await (const response of installationRepositoriesPaginated) {
    for (const repo of response.data) {
      yield repo;
    }
  }
}

And I don't see any relevant diffs from my dependency trees to the one you shared. Interestingly, both @octokit/types and @octokit/openapi-types are missing in your dependency tree, can you think of why?

gr2m avatar Jul 08 '21 21:07 gr2m

@gr2m I did a bit more experimentation and the issue crops up for us between @octokit/[email protected] and @octokit/[email protected], if I downgrade to 18.6.3 it compiles, if I upgrade to 18.6.4 it fails.

bcoe avatar Jul 09 '21 17:07 bcoe

Still no luck on my side reproducing the problem, sorry 😞 Could you create a repository with my test code above that throws the error when building?

gr2m avatar Jul 09 '21 17:07 gr2m

I think it has something todo with the configuration in gts/tsconfig-google.json. I can reproduce the build error with this config

{
  "extends": "./node_modules/gts/tsconfig-google.json",
  "compilerOptions": {
    "lib": ["es2018", "dom"],
    "esModuleInterop": true,
    "rootDir": ".",
    "outDir": "build"
  },
  "include": ["*.ts"]
}

The error does not occur if I remove the extends key

gr2m avatar Jul 09 '21 17:07 gr2m

It's the compilerOptions.strict setting

{
  "compilerOptions": {
    "strict": true,
    "lib": ["es2018"]
  },
  "include": ["*.ts"]
}

gr2m avatar Jul 09 '21 17:07 gr2m

I'll have to get back to this later. We do have the strict setting in https://github.com/octokit/plugin-paginate-rest.js/blob/master/tsconfig.json. I think the next step would be is to add your code as a failing test to https://github.com/octokit/plugin-paginate-rest.js. I have to get back to this next week. If you have time and could add the failing test, that'd be very helpful in moving this forward

gr2m avatar Jul 09 '21 17:07 gr2m

@gr2m thanks for digging into this 👏 I'll play myself with settings.

bcoe avatar Jul 09 '21 18:07 bcoe

I was able to get things compiling by merging strict false into the config, this didn't seem to cause any major issues. Consider this a low priority problem for us currently, thank you for helping figure this out.

bcoe avatar Jul 09 '21 19:07 bcoe

FWIW, we are having the same problem.

honnix avatar Aug 16 '21 13:08 honnix