0

after adding the kiltprotocol/sdk-js to my front-end, I get the following two errors when importing the kilt module.

Error 1:

Type 'Codec | Codec[]' is not assignable to type 'InjectedAccountWithMeta[]'.
          Type 'Codec' is missing the following properties from type 'InjectedAccountWithMeta[]': length, pop, push, concat, and 29 more.
    42 |     });
    43 |
  > 44 |     api.query.council.members((who: InjectedAccountWithMeta[]) => {
       |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    45 |       dispatch1({ type: 'SET_COUNCIL_MEMBERS', payload: who });
    46 |     });
    47 |     api.query.backgroundCouncil.proposals((hash: string[]) => {

Error2:

Type 'Codec | Codec[]' is not assignable to type 'number'.
          Type 'Codec' is not assignable to type 'number'.
    52 |     if (!api || !selectedAccount) return;
    53 |
  > 54 |     api.query.system.number((block: number) => {
       |                             ^^^^^^^^^^^^^^^^^^^^
    55 |       dispatch({ type: 'SET_BLOCKS', payload: block.toString() });
    56 |     });
    57 |   }, [api, selectedAccount, dispatch]);

Without the import of this module, everything works fine. any idea why the types stop being valid, and how to fix it?

Edit1:

I omitted some lines in the error message to make it easier to read, but they actually might be necessary for understanding the source of the problem I will only show Error1, as Error2 is similar:

Error_1_complete:

TS2769: No overload matches this call.
  Overload 1 of 4, '(args_0: (result: Vec<AccountId32>) => void | Promise<void>): UnsubscribePromise', gave the following error.
    Argument of type '(who: InjectedAccountWithMeta[]) => void' is not assignable to parameter of type '(result: Vec<AccountId32>) => void | Promise<void>'.
      Types of parameters 'who' and 'result' are incompatible.
        Type 'Vec<AccountId32>' is not assignable to type 'InjectedAccountWithMeta[]'.
          The types returned by 'pop()' are incompatible between these types.
            Type 'AccountId32 | undefined' is not assignable to type 'InjectedAccountWithMeta | undefined'.
              Type 'GenericAccountId' is missing the following properties from type 'InjectedAccountWithMeta': address, meta
  Overload 2 of 4, '(args_0: (result: Codec | Codec[]) => void | Promise<void>): UnsubscribePromise', gave the following error.
    Argument of type '(who: InjectedAccountWithMeta[]) => void' is not assignable to parameter of type '(result: Codec | Codec[]) => void | Promise<void>'.
      Types of parameters 'who' and 'result' are incompatible.
        Type 'Codec | Codec[]' is not assignable to type 'InjectedAccountWithMeta[]'.
          Type 'Codec' is missing the following properties from type 'InjectedAccountWithMeta[]': length, pop, push, concat, and 29 more.
    43 |     });
    44 |
  > 45 |     api.query.council.members((who: InjectedAccountWithMeta[]) => {
       |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    46 |       dispatch1({ type: 'SET_COUNCIL_MEMBERS', payload: who });
    47 |     });
    48 |     api.query.backgroundCouncil.proposals((hash: string[]) => {

Kazunobu

2
  • 1
    Hi! Have you tried also importing our type augmentation? Add a line with import '@kiltprotocol/augment-api', and let me know if that helps! Aug 17, 2023 at 6:55
  • @AntonioAntonino, I did what you suggested and added: import@"kiltprotocol/augment-api", but the error related to the block type remains. Aug 18, 2023 at 1:07

1 Answer 1

1

Antonio got close to the source of the issue by suggesting adding the api type augmentation, but this actually already happens when you require kiltprotocol/sdk-js. What this does is type polkadot api types more narrowly, including state calls like api.query.council.members (whose return value was typed as a generic Codec type until now).

This reveals that the typings in the callbacks you provided are in fact incorrect. As the first overload suggests, the return type of api.query.council.members actually is a Vec<AccountId32>. The return type of api.query.system.number also definitely is not a JS number type, but a polkadot-js Codec subtype (looked it up, it's a U64).

Changing the typings on your callbacks to align with these types should resolve your issue! Note that you could also change the parameter type to the generic Codec to satisfy TypeScript, but that would not give you access to type-specific methods like map on a Vec.

2
  • Thank you for the hint!!! I changed the parameters types to any in the function declaration, and by converting them back to the type I need inside the function, it works. Aug 21, 2023 at 13:42
  • 1
    sure, that works, but be aware that any effectively circumvents type checking. If you want to make use of TypeScripts static type checking capabilities, I'd recommend using the actual types that reflect what will be fed into your callback at runtime. api.query.council.members((who: Vec<AccountId32>) => { dispatch1({ type: 'SET_COUNCIL_MEMBERS', payload: who }); }); should be working for you; if dispatch1 expects a different structure you should change that or apply transformations in the callback.
    – rflechtner
    Aug 24, 2023 at 17:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.