diff --git a/src/types.ts b/src/types.ts index 45b93f6e0..96d1ef6b7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -30,7 +30,8 @@ export type ReturnTypeOf = T extends AnyFunction ? ReturnType : T extends AnyFunction[] - ? UnionToIntersection> + ? // exclude `void` from intersection, see octokit/octokit.js#2115 + UnionToIntersection, void>> : never; /** diff --git a/test/typescript-validate.ts b/test/typescript-validate.ts index 0cf3eb9ae..979968575 100644 --- a/test/typescript-validate.ts +++ b/test/typescript-validate.ts @@ -4,6 +4,8 @@ import { Octokit } from "../src"; +export function expectType(what: T) {} + export function pluginsTest() { // `octokit` instance does not permit unknown keys const octokit = new Octokit(); @@ -36,4 +38,18 @@ export function pluginsTest() { octokitWithPluginAndDefaults.foo; // @ts-expect-error `.unknown` should not be typed as `any` octokitWithPluginAndDefaults.unknown; + + // https://github.com/octokit/octokit.js/issues/2115 + const OctokitWithVoidAndNonVoidPlugins = Octokit.plugin( + () => ({ foo: "foo" }), + () => {}, + () => ({ bar: "bar" }) + ); + const octokitWithVoidAndNonVoidPlugins = + new OctokitWithVoidAndNonVoidPlugins(); + + // @ts-expect-error octokitWithVoidAndNonVoidPlugins must never be `void`, even if one of the plugins returns `void` + expectType(octokitWithVoidAndNonVoidPlugins); + expectType(octokitWithVoidAndNonVoidPlugins.foo); + expectType(octokitWithVoidAndNonVoidPlugins.bar); }