Skip to content

Commit

Permalink
fix: flatten nested arrays in parseAbiParameters (#232)
Browse files Browse the repository at this point in the history
* fix: flatten nested arrays in parseAbiParameters

* fix: handle empty array and add type tests

* chore: add changeset

* chore: update changeset
  • Loading branch information
xenoliss committed Mar 15, 2024
1 parent f7d5d15 commit 22a5f3a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/cool-buttons-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"abitype": patch
---

Fixed type detection when using an array in `ParseAbiParameters`
48 changes: 48 additions & 0 deletions packages/abitype/src/human-readable/parseAbiParameters.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,52 @@ test('parseAbiParameters', () => {
expectTypeOf(parseAbiParameters(param)).toEqualTypeOf<
readonly AbiParameter[]
>()

expectTypeOf(parseAbiParameters(['(uint256 a),(uint256 b)'])).toEqualTypeOf<
readonly [
{
readonly type: 'tuple'
readonly components: readonly [
{
readonly type: 'uint256'
readonly name: 'a'
},
]
},
{
readonly type: 'tuple'
readonly components: readonly [
{
readonly type: 'uint256'
readonly name: 'b'
},
]
},
]
>()

expectTypeOf(
parseAbiParameters(['(uint256 a)', '(uint256 b)']),
).toEqualTypeOf<
readonly [
{
readonly type: 'tuple'
readonly components: readonly [
{
readonly type: 'uint256'
readonly name: 'a'
},
]
},
{
readonly type: 'tuple'
readonly components: readonly [
{
readonly type: 'uint256'
readonly name: 'b'
},
]
},
]
>()
})
28 changes: 25 additions & 3 deletions packages/abitype/src/human-readable/parseAbiParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,37 @@ export type ParseAbiParameters<
>
: never
} extends infer Mapped extends readonly unknown[]
? Filter<Mapped, never>[0] extends infer Result
? Result extends undefined
? Filter<Mapped, never> extends readonly [...infer Content]
? Content['length'] extends 0
? never
: Result
: DeepFlatten<Content>
: never
: never
: never
: never)

/**
* Flatten all members of {@link T}
*
* @param T - List of items to flatten
* @param Acc - The accumulator used while recursing
* @returns The flattened array
*
* @example
* type Result = DeepFlatten<[['a', 'b'], [['c']]]>
* // ^? type Result = ['a', 'b', 'c']
*/
type DeepFlatten<
T extends readonly unknown[],
Acc extends readonly unknown[] = readonly [],
> = T extends readonly [infer Head, ...infer Tail]
? Tail extends undefined
? never
: Head extends readonly unknown[]
? DeepFlatten<Tail, readonly [...Acc, ...DeepFlatten<Head>]>
: DeepFlatten<Tail, readonly [...Acc, Head]>
: Acc

/**
* Parses human-readable ABI parameters into {@link AbiParameter}s
*
Expand Down

0 comments on commit 22a5f3a

Please sign in to comment.