wevm/abitype

Abi `Zod` schema does not infer to `Abi` type

Closed this issue · 8 comments

Describe the bug

The Zod Abi schema provided from abitype/zod does not match the Abi type from abitype

Link to Minimal Reproducible Example

https://github.com/mathieu-bour/abitype-zod/blob/main/index.ts

Steps To Reproduce

import { Abi } from 'abitype';
import { Abi as AbiSchema } from 'abitype/zod';

const result: Abi = AbiSchema.parse([]);

Package Version

0.9.8

TypeScript Version

5.2.2

Anything else?

TypeScript error:

index.ts:4:7 - error TS2322: Type '({ type: "error"; name: string; inputs: AbiParameter[]; } | { type: "event"; name: string; inputs: (AbiParameter & { indexed?: boolean | undefined; })[]; anonymous?: boolean | undefined; } | ({ ...; } & ({ ...; } | ... 2 more ... | { ...; })))[]' is not assignable to type 'Abi'.
  Type '{ type: "error"; name: string; inputs: AbiParameter[]; } | { type: "event"; name: string; inputs: (AbiParameter & { indexed?: boolean | undefined; })[]; anonymous?: boolean | undefined; } | ({ ...; } & ({ ...; } | ... 2 more ... | { ...; }))' is not assignable to type 'AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive'.
    Type '{ stateMutability: "pure" | "view" | "nonpayable" | "payable"; constant?: boolean | undefined; gas?: number | undefined; payable?: boolean | undefined; } & { type: "constructor"; inputs: AbiParameter[]; }' is not assignable to type 'AbiConstructor | AbiError | AbiEvent | AbiFallback | AbiFunction | AbiReceive'.
      Type '{ stateMutability: "pure" | "view" | "nonpayable" | "payable"; constant?: boolean | undefined; gas?: number | undefined; payable?: boolean | undefined; } & { type: "constructor"; inputs: AbiParameter[]; }' is missing the following properties from type 'AbiFunction': name, outputs

4 const result: Abi = AbiSchema.parse([]);

Validations

This is intended behavior. This comes down to the Abi type using the union of literals "pure" | "view" | "nonpayable" | "payable" and while zod does the same at runtime, at the typelevel it infers that as a string type and not their literal values and string extends "anyliteralvalue" is false so you get that type error when trying to assign that type to the type return from the zod schema parse

The biggest problem is that it makes the Zod extension very difficult to use with abitype itself and viem by extension. I have to make horrible conversions like:

import { Abi } from 'abitype';
import { Abi as AbiSchema } from 'abitype/zod';

const result: Abi = AbiSchema.parse([]) as unknown as Abi;

But why are you assign the ABI to the zod schema parsed? The zod type should be assignable to function were the args expect the Abi type. Here is an example https://tsplay.dev/w2vD9w

My goal is to build a platform where users can submit ABIs via a form. To verify that the submitted data is a valid ABI, I am using import { Abi as AbiSchema } from 'abitype/zod'; to check if the ABI is valid. If the ABI is valid, I will then use viem to interact with the contracts.

import { Abi } from 'abitype';
import { Abi as AbiSchema } from 'abitype/zod';

const validAbi: Abi = AbiSchema.parse(maybeNotAbi); // not assignable to Abi

To sum up, since the AbiSchema is provided by abitype/zod, I would expect a parsed zod Abi to be assignable to abitype's Abi.

You can still do this without having to cast the parsed zod abi to Abi.

Example

Take the example above. Its using viem's getContract function with the zod parsed abi. There is no need here to perform manual casting as this will also works.
Viem docs

However i believed i have found the problem and it should be fixed with #192

Thanks a lot for pointing this to me. While I fully agree that the provided code works, this issue was more about the fact that the Zod schema was not working with the abitype Abi type. However, since there full compatibility with viem, I would consider this issue as "nice-to-have".

I just checked your PR #192 and it looks like that it fixes the issue!

tmm commented

abitype@0.9.9

This issue has been locked since it has been closed for more than 14 days.

If you found a concrete bug or regression related to it, please open a new bug report with a reproduction against the latest ABIType version. If you have any other comments you can create a new discussion.