deno-cliffy icon indicating copy to clipboard operation
deno-cliffy copied to clipboard

TypeError: trying to set a Command via a Command instance instead of providing string description

Open CanRau opened this issue 2 years ago • 6 comments

Trying this, as found in the examples

.command(
    "db",
    new Command()
      .description("add a new database")
      .arguments("<name>")
      .command("add <name>")
      .option("--no-replication", "Don't set-up replication")
      .action((opts, name) => console.log({ opts, name })),
  )

results in

(alias) new Command<void, void, void, [], void, {
    number: number;
    integer: number;
    string: string;
    boolean: boolean;
    file: string;
}, void, undefined>(): Command<void, void, void, [], void, {
    number: number;
    integer: number;
    string: string;
    boolean: boolean;
    file: string;
}, void, undefined>
import Command
No overload matches this call.
  Overload 1 of 2, '(name: string, cmd: Command<void | { someOtherEnvVar?: (NumberType & number) | undefined; } | undefined, void | { number: number; integer: number; string: string; boolean: boolean; file: string; } | undefined, ... 5 more ..., Command<...> | undefined>, override?: boolean | undefined): Command<...>', gave the following error.
    Argument of type 'Command<void, void, { replication: boolean; }, [string], void, void, void, Command<void, void, void, [string], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>>' is not assignable to parameter of type 'Command<void | { someOtherEnvVar?: (NumberType & number) | undefined; } | undefined, void | { number: number; integer: number; string: string; boolean: boolean; file: string; } | undefined, ... 5 more ..., Command<...> | undefined>'.
      Types of property '_parent' are incompatible.
        Type 'Command<void, void, void, [string], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined> | undefined' is not assignable to type 'Command<void, void, void, [string], { someOtherEnvVar?: (NumberType & number) | undefined; }, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined> | undefined'.
          Type 'Command<void, void, void, [string], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>' is not assignable to type 'Command<void, void, void, [string], { someOtherEnvVar?: (NumberType & number) | undefined; }, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>'.  Overload 2 of 2, '(name: "db", desc?: string | undefined, override?: boolean | undefined): Command<{ someOtherEnvVar?: (NumberType & number) | undefined; }, void, void, [], void, void, void, Command<...>>', gave the following error.
    Argument of type 'Command<void, void, { replication: boolean; }, [string], void, void, void, Command<void, void, void, [string], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>>' is not assignable to parameter of type 'string'.deno-ts(2769)

though setting --no-check the command works as expected.

Update: just realized this type error just pops up when I've got a globalEnv anywhere before the .command() 😳 after or when removing the error goes away 🤗

CanRau avatar May 29 '22 05:05 CanRau

Just got a new error when refactoring to have

const dbCommand = new Command()
  .description("Database commands")
  .command("add <name>", dbAddCommand);

and in the main Command

.command("db", dbCommand)
const dbCommand: Command<void, {
    number: number;
    integer: number;
    string: string;
    boolean: boolean;
    file: string;
}, Omit<{
    user?: true | undefined;
} & {
    password?: true | undefined;
}, "replication"> & ... 4 more ... & {
    ...;
}, ... 4 more ..., Command<...>>
No overload matches this call.
  Overload 1 of 2, '(name: string, cmd: Command<void | undefined, void | { number: number; integer: number; string: string; boolean: boolean; file: string; } | undefined, void | Record<string, any>, ... 4 more ..., Command<...> | undefined>, override?: boolean | undefined): Command<...>', gave the following error.
    Argument of type 'Command<void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, Omit<{ user?: true | undefined; } & { password?: true | undefined; }, "replication"> & ... 4 more ... & { ...; }, ... 4 more ..., Command<...>>' is not assignable to parameter of type 'Command<void | undefined, void | { number: number; integer: number; string: string; boolean: boolean; file: string; } | undefined, void | Record<string, any>, unknown[], void | Record<string, any>, void | Record<...>, void | Record<...>, Command<...> | undefined>'.
      Types of property '_parent' are incompatible.
        Type 'Command<void, void, void, [], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined> | undefined' is not assignable to type 'Command<void, void, void, [string], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined> | undefined'.
          Type 'Command<void, void, void, [], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>' is not assignable to type 'Command<void, void, void, [string], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>'.  Overload 2 of 2, '(name: "db", desc?: string | undefined, override?: boolean | undefined): Command<void, void, void, [], void, void, void, Command<void, void, void, [string], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>>', gave the following error.
    Argument of type 'Command<void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, Omit<{ user?: true | undefined; } & { password?: true | undefined; }, "replication"> & ... 4 more ... & { ...; }, ... 4 more ..., Command<...>>' is not assignable to parameter of type 'string'.deno-ts(2769)

CanRau avatar May 29 '22 06:05 CanRau

thx @CanRau, i opened a PR with a fix for this. does this work for you now? you can test it with this url: https://raw.githubusercontent.com/c4spar/deno-cliffy/81fb4d8e59ae7ec8f9a2f7864a546c4d0146c15b/command/mod.ts

c4spar avatar May 29 '22 13:05 c4spar

Solves the former issue yes but I now get

error: TS2589 [ERROR]: Type instantiation is excessively deep and possibly infinite.
const dbCommand = new Command()

which refers to

const dbCommand = new Command()
  .description("Database commands")
  .arguments("<subcommand>")
  .command("add <name>", dbAddCommand)
  .command("replicate", dbReplicateCommand)
  .command("delete", dbDeleteCommand);

which is then used in the main Command

new Command()
  .command("db", dbCommand)

CanRau avatar May 30 '22 16:05 CanRau

yeah i noticed this as well. will try to improve th performence.

as workaround you can call the .reset() method on your sub commands, than there shuld be no type error.

const dbCommand = new Command()
  .description("Database commands")
  .arguments("<subcommand>")
  .command("add <name>", dbAddCommand.reset())
  .command("replicate", dbReplicateCommand.reset())
  .command("delete", dbDeleteCommand.reset());

c4spar avatar May 30 '22 17:05 c4spar

I came here for this.

Upgrading a Cliffy app resulted in this same issue. Note, It's easy to see it fail with the example code in the docs.

https://cliffy.io/[email protected]/command/options#global-options

❯ deno run index.ts command1 command2 -g
Check file:///Users/glenn/tmp/cliffy/index.ts
error: TS2769 [ERROR]: No overload matches this call.
  Overload 1 of 2, '(name: string, cmd: Command<void | { global?: true | (StringType & string) | undefined; } | undefined, void | { number: number; integer: number; string: string; boolean: boolean; file: string; } | undefined, ... 5 more ..., Command<...> | undefined>, override?: boolean | undefined): Command<...>', gave the following error.
    Argument of type 'Command<void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, [], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, Command<...>>' is not assignable to parameter of type 'Command<void | { global?: true | (StringType & string) | undefined; } | undefined, void | { number: number; integer: number; string: string; boolean: boolean; file: string; } | undefined, ... 5 more ..., Command<...> | undefined>'.
      Types of property '_parent' are incompatible.
        Type 'Command<void, void, void, [], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined> | undefined' is not assignable to type 'Command<void, void, { local?: true | (StringType & string) | undefined; }, [], { global?: true | (StringType & string) | undefined; }, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined> | undefined'.
          Type 'Command<void, void, void, [], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>' is not assignable to type 'Command<void, void, { local?: true | (StringType & string) | undefined; }, [], { global?: true | (StringType & string) | undefined; }, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, undefined>'.  Overload 2 of 2, '(name: "command1", desc?: string | undefined, override?: boolean | undefined): Command<{ global?: true | (StringType & string) | undefined; }, void, void, [], void, void, void, Command<...>>', gave the following error.
    Argument of type 'Command<void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, [], void, { number: number; integer: number; string: string; boolean: boolean; file: string; }, void, Command<...>>' is not assignable to parameter of type 'string'.
    new Command()
    ^
    at file:///Users/glenn/tmp/cliffy/index.ts:12:5

TS2793 [ERROR]:     The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.
      command(
      ~~~~~~~
        at https://deno.land/x/[email protected]/command/command.ts:312:3

As suggested, adding a single reset() on command1 cleared it up.

import { Command } from "https://deno.land/x/[email protected]/command/mod.ts";

await new Command()
  .option("-l, --local [val:string]", "Only available on this command.")
  .globalOption(
    "-g, --global [val:string]",
    "Available on this and all nested child commands.",
  )
  .action(console.log)
  .command(
    "command1",
    new Command()
      .description("Some sub command.")
      .action(console.log)
      .command(
        "command2",
        new Command()
          .description("Some nested sub command.")
          .action(console.log),
      ).reset(),
  )
  .parse(Deno.args);
❯ deno run index.ts command1 command2 -g
{ global: true }

grempe avatar May 31 '22 15:05 grempe

@grempe could you check please if it works for you without calling the .reset() method if you import cliffy from this url https://github.com/c4spar/deno-cliffy/blob/78a31cc494fbe6fe14f94efd5087df387018ffaa/command/mod.ts?

Or do you also get this performance issue?

error: TS2589 [ERROR]: Type instantiation is excessively deep and possibly infinite.

c4spar avatar Jul 27 '22 21:07 c4spar

I have closed this issue as the original issue has been fixed. If anyone is still having performance issues, please open a new issue with a reproducible example because I can't reproduce this issue rn.

c4spar avatar Aug 30 '22 22:08 c4spar