Skip to content

fix: discriminate overloaded function args#156

Open
FarajiOranj wants to merge 1 commit into
ryangoree:mainfrom
FarajiOranj:feat/discriminate-overloaded-args
Open

fix: discriminate overloaded function args#156
FarajiOranj wants to merge 1 commit into
ryangoree:mainfrom
FarajiOranj:feat/discriminate-overloaded-args

Conversation

@FarajiOranj

Copy link
Copy Markdown

Summary

Closes #132.

Makes the inferred args type for overloaded functions (and events) a
discriminated union, so only the arguments of a single overload can be used at a
time.

Before, for an overloaded foo(uint256 num) / foo(string name):

type FooArgs = FunctionArgs<OverloadedAbi, "foo">;
//   ^? { num: bigint } | { name: string }

client.read({ abi, address, fn: "foo", args: { num: 123n, name: "abc" } });
//                                            ^ both allowed (the bug)

After:

type FooArgs = FunctionArgs<OverloadedAbi, "foo">;
//   ^? OneOfNamed<{ num: bigint } | { name: string }>

client.read({ abi, address, fn: "foo", args: { num: 123n, name: "abc" } });
//                                                         ^ Type 'bigint' is not
//                                                           assignable to type 'undefined'

Changes

  • AbiObjectType (in Abi.ts) now wraps its result in a discriminated union.
    This flows into FunctionArgs, ConstructorArgs, and EventArgs (all args).
    FunctionReturn uses AbiSimplifiedType and is intentionally unchanged, so
    return values stay a plain union.
  • Added two type utilities: OneOfNamed and NamedUnionKey. OneOfNamed is
    like the existing OneOf, but it only counts named keys when negating other
    members and returns a non-union type unchanged. This keeps it correct when an
    overload set includes a no-arg signature (whose "empty" object would otherwise
    poison the other members with [x: string]: undefined index signatures), and
    avoids changing the widely-used OneOf (so CallParams/prepareCall etc. are
    unaffected).

Tests

Added Function.test-d.ts type-tests covering discrimination for overloads with
different arg names, different arity, shared names, and a no-arg-plus-named
overload set, plus no-regression checks for single/no-arg functions and
FunctionReturn. This is a type-only change, so the runtime suite is unchanged.

`FunctionArgs` (and `ConstructorArgs`/`EventArgs`) for an overloaded entry
inferred a plain union of each overload's args, which let callers mix args
from different overloads (e.g. `{ num, name }` for `foo(uint256) | foo(string)`).

Wrap `AbiObjectType` in a new `OneOfNamed` discriminated-union helper so only a
single overload's args can be used at a time. `OneOfNamed` is like `OneOf` but
counts only named keys (so a no-arg overload's empty object doesn't pollute the
other members with index signatures) and leaves a non-union type unchanged;
the widely-used `OneOf` is untouched. `FunctionReturn` is unaffected.

Adds `OneOfNamed`/`NamedUnionKey` utilities and type-tests.
@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 01df456

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@gud/drift Patch
@gud/drift-ethers-v5 Patch
@gud/drift-ethers Patch
@gud/drift-viem Patch
@gud/drift-web3 Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discriminate overloaded function args

1 participant