Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tangy-apples-read.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"abitype": patch
---

feat: support custom names in experimental_namedTuples register option
4 changes: 2 additions & 2 deletions docs/pages/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ declare module 'abitype' {

### `experimental_namedTuples`

Enables named tuple generation in [`AbiParametersToPrimitiveTypes`](/api/utilities#abiparameterstoprimitivetypes) for common ABI parameter names.
Enables named tuple generation in [`AbiParametersToPrimitiveTypes`](/api/utilities#abiparameterstoprimitivetypes) for common ABI parameter names. When a string array, adds custom names.

- Type `boolean`
- Type `boolean | readonly string[]`
- Default `false`

```ts twoslash
Expand Down
3 changes: 3 additions & 0 deletions packages/abitype/src/register.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ test('ResolvedRegister', () => {

type StrictAbiType = ResolvedRegister['strictAbiType']
assertType<StrictAbiType>(false)

type ExperimentalNamedTuples = ResolvedRegister['experimental_namedTuples']
assertType<ExperimentalNamedTuples>(false)
})
5 changes: 2 additions & 3 deletions packages/abitype/src/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,11 @@ export type ResolvedRegister = {
: DefaultRegister['fixedArrayMaxLength']

/**
* Enables named tuple generation in {@link AbiParametersToPrimitiveTypes} for common ABI parameter names.
*
* Enables named tuple generation in {@link AbiParametersToPrimitiveTypes} for common ABI parameter names. When a string array, adds custom names.
* @default false
*/
experimental_namedTuples: Register extends {
experimental_namedTuples: infer type extends boolean
experimental_namedTuples: infer type extends boolean | readonly string[]
}
? type
: DefaultRegister['experimental_namedTuples']
Expand Down
87 changes: 59 additions & 28 deletions packages/abitype/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,17 @@ export type AbiParametersToPrimitiveTypes<
abiParameterKind extends AbiParameterKind = AbiParameterKind,
///
experimental_namedTuples extends
boolean = ResolvedRegister['experimental_namedTuples'],
> = experimental_namedTuples extends true
? AbiParametersToPrimitiveTypes_named<abiParameters, abiParameterKind>
: AbiParametersToPrimitiveTypes_mapped<abiParameters, abiParameterKind>
| boolean
| readonly string[] = ResolvedRegister['experimental_namedTuples'],
> = experimental_namedTuples extends false
? AbiParametersToPrimitiveTypes_mapped<abiParameters, abiParameterKind>
: AbiParametersToPrimitiveTypes_named<
abiParameters,
abiParameterKind,
experimental_namedTuples extends readonly string[]
? experimental_namedTuples
: readonly []
>

export type AbiParametersToPrimitiveTypes_mapped<
abiParameters extends readonly AbiParameter[],
Expand All @@ -209,6 +216,7 @@ export type AbiParametersToPrimitiveTypes_mapped<
export type AbiParametersToPrimitiveTypes_named<
abiParameters extends readonly AbiParameter[],
abiParameterKind extends AbiParameterKind = AbiParameterKind,
customNames extends readonly string[] = readonly [],
///
acc extends readonly unknown[] = [],
depth extends readonly number[] = [],
Expand All @@ -231,14 +239,15 @@ export type AbiParametersToPrimitiveTypes_named<
? AbiParametersToPrimitiveTypes_named<
tail,
abiParameterKind,
customNames,
readonly [
...acc,
...ToNamedTuple<head1, abiParameterKind>,
...ToNamedTuple<head2, abiParameterKind>,
...ToNamedTuple<head3, abiParameterKind>,
...ToNamedTuple<head4, abiParameterKind>,
...ToNamedTuple<head5, abiParameterKind>,
...ToNamedTuple<head6, abiParameterKind>,
...ToNamedTuple<head1, abiParameterKind, customNames>,
...ToNamedTuple<head2, abiParameterKind, customNames>,
...ToNamedTuple<head3, abiParameterKind, customNames>,
...ToNamedTuple<head4, abiParameterKind, customNames>,
...ToNamedTuple<head5, abiParameterKind, customNames>,
...ToNamedTuple<head6, abiParameterKind, customNames>,
],
[...depth, 1]
>
Expand All @@ -251,11 +260,11 @@ export type AbiParametersToPrimitiveTypes_named<
]
? readonly [
...acc,
...ToNamedTuple<head1, abiParameterKind>,
...ToNamedTuple<head2, abiParameterKind>,
...ToNamedTuple<head3, abiParameterKind>,
...ToNamedTuple<head4, abiParameterKind>,
...ToNamedTuple<head5, abiParameterKind>,
...ToNamedTuple<head1, abiParameterKind, customNames>,
...ToNamedTuple<head2, abiParameterKind, customNames>,
...ToNamedTuple<head3, abiParameterKind, customNames>,
...ToNamedTuple<head4, abiParameterKind, customNames>,
...ToNamedTuple<head5, abiParameterKind, customNames>,
]
: abiParameters extends readonly [
infer head1 extends AbiParameter,
Expand All @@ -265,10 +274,10 @@ export type AbiParametersToPrimitiveTypes_named<
]
? readonly [
...acc,
...ToNamedTuple<head1, abiParameterKind>,
...ToNamedTuple<head2, abiParameterKind>,
...ToNamedTuple<head3, abiParameterKind>,
...ToNamedTuple<head4, abiParameterKind>,
...ToNamedTuple<head1, abiParameterKind, customNames>,
...ToNamedTuple<head2, abiParameterKind, customNames>,
...ToNamedTuple<head3, abiParameterKind, customNames>,
...ToNamedTuple<head4, abiParameterKind, customNames>,
]
: abiParameters extends readonly [
infer head1 extends AbiParameter,
Expand All @@ -277,21 +286,24 @@ export type AbiParametersToPrimitiveTypes_named<
]
? readonly [
...acc,
...ToNamedTuple<head1, abiParameterKind>,
...ToNamedTuple<head2, abiParameterKind>,
...ToNamedTuple<head3, abiParameterKind>,
...ToNamedTuple<head1, abiParameterKind, customNames>,
...ToNamedTuple<head2, abiParameterKind, customNames>,
...ToNamedTuple<head3, abiParameterKind, customNames>,
]
: abiParameters extends readonly [
infer head1 extends AbiParameter,
infer head2 extends AbiParameter,
]
? readonly [
...acc,
...ToNamedTuple<head1, abiParameterKind>,
...ToNamedTuple<head2, abiParameterKind>,
...ToNamedTuple<head1, abiParameterKind, customNames>,
...ToNamedTuple<head2, abiParameterKind, customNames>,
]
: abiParameters extends readonly [infer head extends AbiParameter]
? readonly [...acc, ...ToNamedTuple<head, abiParameterKind>]
? readonly [
...acc,
...ToNamedTuple<head, abiParameterKind, customNames>,
]
: acc extends readonly []
? abiParameters extends readonly []
? readonly []
Expand All @@ -301,12 +313,31 @@ export type AbiParametersToPrimitiveTypes_named<
type ToNamedTuple<
abiParameter extends AbiParameter,
abiParameterKind extends AbiParameterKind,
customNames extends readonly string[] = readonly [],
> = unwrapName<
AbiParameterToPrimitiveType<abiParameter, abiParameterKind>,
abiParameter['name']
abiParameter['name'],
customNames
>
type unwrapName<type, name> = name extends string
? AbiParameterTupleNameLookup<type>[name]

type CustomTupleNameLookup<
type,
customNames extends readonly string[],
> = customNames extends readonly []
? {}
: { [K in customNames[number]]: [K: type] }

type MergedTupleNameLookup<
type,
customNames extends readonly string[],
> = AbiParameterTupleNameLookup<type> & CustomTupleNameLookup<type, customNames>

type unwrapName<
type,
name,
customNames extends readonly string[] = readonly [],
> = name extends string
? MergedTupleNameLookup<type, customNames>[name]
: [type]

/**
Expand Down
11 changes: 11 additions & 0 deletions packages/register-tests/named-tuples/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "named-tuples-register",
"private": true,
"type": "module",
"scripts": {
"check:types": "tsc --noEmit"
},
"dependencies": {
"abitype": "workspace:*"
}
}
40 changes: 40 additions & 0 deletions packages/register-tests/named-tuples/src/named-tuples.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { AbiParametersToPrimitiveTypes } from 'abitype'
import { describe, expectTypeOf, test } from 'vitest'

describe('experimental_namedTuples', () => {
test('common names', () => {
type Result = AbiParametersToPrimitiveTypes<
[{ name: 'amount'; type: 'uint256' }]
>
expectTypeOf<Result>().toEqualTypeOf<readonly [amount: bigint]>()
})

test('custom names', () => {
type Result1 = AbiParametersToPrimitiveTypes<
[{ name: 'myCustomParam'; type: 'uint256' }]
>
expectTypeOf<Result1>().toEqualTypeOf<readonly [myCustomParam: bigint]>()

type Result2 = AbiParametersToPrimitiveTypes<
[{ name: 'projectSpecificName'; type: 'address' }]
>
expectTypeOf<Result2>().toEqualTypeOf<
readonly [projectSpecificName: `0x${string}`]
>()

type Mixed = AbiParametersToPrimitiveTypes<
[
{ name: 'myCustomParam'; type: 'uint256' },
{ name: 'amount'; type: 'uint256' },
{ name: 'projectSpecificName'; type: 'address' },
]
>
expectTypeOf<Mixed>().toEqualTypeOf<
readonly [
myCustomParam: bigint,
amount: bigint,
projectSpecificName: `0x${string}`,
]
>()
})
})
5 changes: 5 additions & 0 deletions packages/register-tests/named-tuples/src/register.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module 'abitype' {
interface Register {
experimental_namedTuples: ['myCustomParam', 'projectSpecificName']
}
}
5 changes: 5 additions & 0 deletions packages/register-tests/named-tuples/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": []
}
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.