Comparing version 0.0.0-canary.20231201T171022 to 0.0.0-canary.20240117T190425
@@ -9,3 +9,3 @@ "use strict"; | ||
details: `parseAbiItem(${JSON.stringify(signature, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiitem-1', | ||
docsPath: '/api/human#parseabiitem-1', | ||
}); | ||
@@ -12,0 +12,0 @@ Object.defineProperty(this, "name", { |
@@ -9,3 +9,3 @@ "use strict"; | ||
details: `parseAbiParameter(${JSON.stringify(param, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiparameter-1', | ||
docsPath: '/api/human#parseabiparameter-1', | ||
}); | ||
@@ -25,3 +25,3 @@ Object.defineProperty(this, "name", { | ||
details: `parseAbiParameters(${JSON.stringify(params, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiparameters-1', | ||
docsPath: '/api/human#parseabiparameters-1', | ||
}); | ||
@@ -28,0 +28,0 @@ Object.defineProperty(this, "name", { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.version = void 0; | ||
exports.version = '0.0.0-canary.20231201T171022'; | ||
exports.version = '0.0.0-canary.20240117T190425'; | ||
//# sourceMappingURL=version.js.map |
@@ -6,3 +6,3 @@ import { BaseError } from '../../errors.js'; | ||
details: `parseAbiItem(${JSON.stringify(signature, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiitem-1', | ||
docsPath: '/api/human#parseabiitem-1', | ||
}); | ||
@@ -9,0 +9,0 @@ Object.defineProperty(this, "name", { |
@@ -6,3 +6,3 @@ import { BaseError } from '../../errors.js'; | ||
details: `parseAbiParameter(${JSON.stringify(param, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiparameter-1', | ||
docsPath: '/api/human#parseabiparameter-1', | ||
}); | ||
@@ -21,3 +21,3 @@ Object.defineProperty(this, "name", { | ||
details: `parseAbiParameters(${JSON.stringify(params, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiparameters-1', | ||
docsPath: '/api/human#parseabiparameters-1', | ||
}); | ||
@@ -24,0 +24,0 @@ Object.defineProperty(this, "name", { |
@@ -1,2 +0,2 @@ | ||
export const version = '0.0.0-canary.20231201T171022'; | ||
export const version = '0.0.0-canary.20240117T190425'; | ||
//# sourceMappingURL=version.js.map |
@@ -1,2 +0,2 @@ | ||
import type { Abi, AbiParameter, AbiParameterKind, AbiStateMutability, AbiType, MBits, SolidityAddress, SolidityArray, SolidityBool, SolidityBytes, SolidityFixedArrayRange, SolidityFixedArraySizeLookup, SolidityFunction, SolidityInt, SolidityString, SolidityTuple, TypedData, TypedDataParameter, TypedDataType } from './abi.js'; | ||
import type { Abi, AbiParameter, AbiParameterKind, AbiStateMutability, AbiType, MBits, SolidityArray, SolidityBytes, SolidityFixedArrayRange, SolidityFixedArraySizeLookup, SolidityInt, SolidityTuple, TypedData, TypedDataParameter, TypedDataType } from './abi.js'; | ||
import type { ResolvedRegister } from './register.js'; | ||
@@ -13,29 +13,24 @@ import type { Error, Merge, Pretty, Tuple } from './types.js'; | ||
*/ | ||
export type AbiTypeToPrimitiveType<TAbiType extends AbiType, TAbiParameterKind extends AbiParameterKind = AbiParameterKind> = PrimitiveTypeLookup<TAbiType, TAbiParameterKind>[TAbiType]; | ||
type PrimitiveTypeLookup<TAbiType extends AbiType, TAbiParameterKind extends AbiParameterKind = AbiParameterKind> = { | ||
[_ in SolidityAddress]: ResolvedRegister['AddressType']; | ||
} & { | ||
[_ in SolidityBool]: boolean; | ||
} & { | ||
[_ in SolidityBytes]: ResolvedRegister['BytesType'][TAbiParameterKind]; | ||
} & { | ||
[_ in SolidityFunction]: `${ResolvedRegister['AddressType']}${string}`; | ||
} & { | ||
[_ in SolidityInt]: TAbiType extends `${'u' | ''}int${infer TBits}` ? TBits extends keyof BitsTypeLookup ? BitsTypeLookup[TBits] : Error<'Unknown bits value.'> : Error<`Unknown 'SolidityInt' format.`>; | ||
} & { | ||
[_ in SolidityString]: string; | ||
} & { | ||
[_ in SolidityTuple]: Record<string, unknown>; | ||
} & { | ||
export type AbiTypeToPrimitiveType<TAbiType extends AbiType, TAbiParameterKind extends AbiParameterKind = AbiParameterKind> = TAbiType extends SolidityBytes ? PrimitiveTypeLookup[TAbiType][TAbiParameterKind] : PrimitiveTypeLookup[TAbiType]; | ||
interface PrimitiveTypeLookup extends SolidityIntMap, SolidityByteMap, SolidityArrayMap { | ||
address: ResolvedRegister['AddressType']; | ||
bool: boolean; | ||
function: `${ResolvedRegister['AddressType']}${string}`; | ||
string: string; | ||
tuple: Record<string, unknown>; | ||
} | ||
type SolidityIntMap = { | ||
[_ in SolidityInt]: _ extends `${'u' | ''}int${infer TBits extends keyof BitsTypeLookup}` ? BitsTypeLookup[TBits] : never; | ||
}; | ||
type SolidityByteMap = { | ||
[_ in SolidityBytes]: ResolvedRegister['BytesType']; | ||
}; | ||
type SolidityArrayMap = { | ||
[_ in SolidityArray]: readonly unknown[]; | ||
}; | ||
type GreaterThan48Bits = Exclude<MBits, 8 | 16 | 24 | 32 | 40 | 48 | ''>; | ||
type LessThanOrEqualTo48Bits = Exclude<MBits, GreaterThan48Bits | ''>; | ||
type NoBits = Exclude<MBits, GreaterThan48Bits | LessThanOrEqualTo48Bits>; | ||
type GreaterThan48Bits = Exclude<MBits, 8 | 16 | 24 | 32 | 40 | 48 | NoBits>; | ||
type LessThanOrEqualTo48Bits = Exclude<MBits, GreaterThan48Bits | NoBits>; | ||
type NoBits = ''; | ||
type BitsTypeLookup = { | ||
[_ in `${LessThanOrEqualTo48Bits}`]: ResolvedRegister['IntType']; | ||
} & { | ||
[_ in `${GreaterThan48Bits}`]: ResolvedRegister['BigIntType']; | ||
} & { | ||
[_ in NoBits]: ResolvedRegister['BigIntType']; | ||
[K in MBits]: ResolvedRegister[K extends LessThanOrEqualTo48Bits ? 'IntType' : 'BigIntType']; | ||
}; | ||
@@ -52,14 +47,18 @@ /** | ||
type: unknown; | ||
}, TAbiParameterKind extends AbiParameterKind = AbiParameterKind> = TAbiParameter['type'] extends Exclude<AbiType, SolidityTuple | SolidityArray> ? AbiTypeToPrimitiveType<TAbiParameter['type'], TAbiParameterKind> : TAbiParameter extends { | ||
}, TAbiParameterKind extends AbiParameterKind = AbiParameterKind> = TAbiParameter['type'] extends AbiBasicType ? AbiTypeToPrimitiveType<TAbiParameter['type'], TAbiParameterKind> : TAbiParameter extends { | ||
type: SolidityTuple; | ||
components: infer TComponents extends readonly AbiParameter[]; | ||
} ? TComponents extends readonly [] ? [] : _HasUnnamedAbiParameter<TComponents> extends true ? readonly [ | ||
...{ | ||
[K in keyof TComponents]: AbiParameterToPrimitiveType<TComponents[K], TAbiParameterKind>; | ||
} | ||
] : { | ||
[Component in TComponents[number] as Component extends { | ||
name: string; | ||
} ? Component['name'] : never]: AbiParameterToPrimitiveType<Component, TAbiParameterKind>; | ||
} : | ||
} ? AbiComponentsToPrimitiveType<TComponents, TAbiParameterKind> : MaybeExtractArrayParameterType<TAbiParameter['type']> extends [ | ||
infer Head extends string, | ||
infer Size | ||
] ? AbiArrayToPrimitiveType<TAbiParameter, TAbiParameterKind, Head, Size> : ResolvedRegister['StrictAbiType'] extends true ? Error<`Unknown type '${TAbiParameter['type'] & string}'.`> : TAbiParameter extends { | ||
components: Error<string>; | ||
} ? TAbiParameter['components'] : unknown; | ||
type AbiBasicType = Exclude<AbiType, SolidityTuple | SolidityArray>; | ||
type AbiComponentsToPrimitiveType<Components extends readonly AbiParameter[], TAbiParameterKind extends AbiParameterKind> = Components extends readonly [] ? [] : Components[number]['name'] extends Exclude<Components[number]['name'] & string, undefined | ''> ? { | ||
[Component in Components[number] as Component['name'] & {}]: AbiParameterToPrimitiveType<Component, TAbiParameterKind>; | ||
} : { | ||
[I in keyof Components]: AbiParameterToPrimitiveType<Components[I], TAbiParameterKind>; | ||
}; | ||
type MaybeExtractArrayParameterType<T> = | ||
/** | ||
@@ -73,15 +72,11 @@ * First, infer `Head` against a known size type (either fixed-length array value or `""`). | ||
*/ | ||
TAbiParameter['type'] extends `${infer Head}[${'' | `${SolidityFixedArrayRange}`}]` ? TAbiParameter['type'] extends `${Head}[${infer Size}]` ? Size extends keyof SolidityFixedArraySizeLookup ? Tuple<AbiParameterToPrimitiveType<Merge<TAbiParameter, { | ||
T extends `${infer Head}[${'' | `${SolidityFixedArrayRange}`}]` ? T extends `${Head}[${infer Size}]` ? [Head, Size] : undefined : undefined; | ||
type AbiArrayToPrimitiveType<TAbiParameter extends AbiParameter | { | ||
name: string; | ||
type: unknown; | ||
}, TAbiParameterKind extends AbiParameterKind, Head extends string, Size> = Size extends keyof SolidityFixedArraySizeLookup ? Tuple<AbiParameterToPrimitiveType<Merge<TAbiParameter, { | ||
type: Head; | ||
}>, TAbiParameterKind>, SolidityFixedArraySizeLookup[Size]> : readonly AbiParameterToPrimitiveType<Merge<TAbiParameter, { | ||
type: Head; | ||
}>, TAbiParameterKind>[] : never : ResolvedRegister['StrictAbiType'] extends true ? TAbiParameter['type'] extends infer TAbiType extends string ? Error<`Unknown type '${TAbiType}'.`> : never : TAbiParameter extends { | ||
components: Error<string>; | ||
} ? TAbiParameter['components'] : unknown; | ||
type _HasUnnamedAbiParameter<TAbiParameters extends readonly AbiParameter[]> = TAbiParameters extends readonly [ | ||
infer Head extends AbiParameter, | ||
...infer Tail extends readonly AbiParameter[] | ||
] ? Head extends { | ||
name: string; | ||
} ? Head['name'] extends '' ? true : _HasUnnamedAbiParameter<Tail> : true : false; | ||
}>, TAbiParameterKind>[]; | ||
/** | ||
@@ -220,3 +215,3 @@ * Converts array of {@link AbiParameter} to corresponding TypeScript primitive types. | ||
}; | ||
}; | ||
} & unknown; | ||
type _TypedDataParametersToAbiParameters<TTypedDataParameters extends readonly TypedDataParameter[], TTypedData extends TypedData, TKeyReferences extends { | ||
@@ -223,0 +218,0 @@ [_: string]: unknown; |
@@ -1,2 +0,2 @@ | ||
export declare const version = "0.0.0-canary.20231201T171022"; | ||
export declare const version = "0.0.0-canary.20240117T190425"; | ||
//# sourceMappingURL=version.d.ts.map |
{ | ||
"name": "abitype", | ||
"description": "Strict TypeScript types for Ethereum ABIs", | ||
"version": "0.0.0-canary.20231201T171022", | ||
"version": "0.0.0-canary.20240117T190425", | ||
"license": "MIT", | ||
@@ -13,3 +13,5 @@ "repository": "wevm/abitype", | ||
"test:build": "publint --strict", | ||
"typecheck": "tsc --noEmit" | ||
"typebench": "tsx src/**.bench-d.ts --benchPercentThreshold 20 --benchErrorOnThresholdExceeded", | ||
"typecheck": "tsc --noEmit", | ||
"typeperf": "tsc --noEmit --extendedDiagnostics --composite false --incremental false" | ||
}, | ||
@@ -23,2 +25,3 @@ "files": [ | ||
"!src/**/*.bench.ts", | ||
"!src/**/*.bench-d.ts", | ||
"/abis", | ||
@@ -79,4 +82,4 @@ "/zod" | ||
"contributors": [ | ||
"awkweb.eth <t@wagmi.sh>", | ||
"jxom.eth <j@wagmi.sh>" | ||
"awkweb.eth <t@wevm.dev>", | ||
"jxom.eth <j@wevm.dev>" | ||
], | ||
@@ -88,9 +91,9 @@ "funding": "https://github.com/sponsors/wevm", | ||
"ethereum", | ||
"types", | ||
"typescript", | ||
"types", | ||
"web3", | ||
"viem", | ||
"wagmi", | ||
"web3", | ||
"wevm" | ||
] | ||
} |
@@ -72,6 +72,6 @@ <br/> | ||
- You want to [typecheck](https://abitype.dev/api/types.html) your ABIs or EIP-712 Typed Data. | ||
- You want to [typecheck](https://abitype.dev/api/types) your ABIs or EIP-712 Typed Data. | ||
- You want to add type inference and autocomplete to your library based on user-provided ABIs or EIP-712 Typed Data, like [wagmi](https://wagmi.sh) and [viem](https://viem.sh). | ||
- You need to [convert ABI types](https://abitype.dev/api/utilities.html#abiparameterstoprimitivetypes) (e.g. `'string'`) to TypeScript types (e.g. `string`) or other type transformations. | ||
- You need to validate ABIs at [runtime](https://abitype.dev/api/zod.html) (e.g. after fetching from external resource). | ||
- You need to [convert ABI types](https://abitype.dev/api/utilities#abiparameterstoprimitivetypes) (e.g. `'string'`) to TypeScript types (e.g. `string`) or other type transformations. | ||
- You need to validate ABIs at [runtime](https://abitype.dev/api/zod) (e.g. after fetching from external resource). | ||
- You don’t want to set up a build process to generate types (e.g. TypeChain). | ||
@@ -78,0 +78,0 @@ |
@@ -9,3 +9,3 @@ import { BaseError } from '../../errors.js' | ||
details: `parseAbiItem(${JSON.stringify(signature, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiitem-1', | ||
docsPath: '/api/human#parseabiitem-1', | ||
}) | ||
@@ -12,0 +12,0 @@ } |
@@ -11,3 +11,3 @@ import type { AbiItemType, AbiParameter } from '../../abi.js' | ||
details: `parseAbiParameter(${JSON.stringify(param, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiparameter-1', | ||
docsPath: '/api/human#parseabiparameter-1', | ||
}) | ||
@@ -23,3 +23,3 @@ } | ||
details: `parseAbiParameters(${JSON.stringify(params, null, 2)})`, | ||
docsPath: '/api/human.html#parseabiparameters-1', | ||
docsPath: '/api/human#parseabiparameters-1', | ||
}) | ||
@@ -26,0 +26,0 @@ } |
231
src/utils.ts
@@ -8,11 +8,7 @@ import type { | ||
MBits, | ||
SolidityAddress, | ||
SolidityArray, | ||
SolidityBool, | ||
SolidityBytes, | ||
SolidityFixedArrayRange, | ||
SolidityFixedArraySizeLookup, | ||
SolidityFunction, | ||
SolidityInt, | ||
SolidityString, | ||
SolidityTuple, | ||
@@ -38,40 +34,41 @@ TypedData, | ||
TAbiParameterKind extends AbiParameterKind = AbiParameterKind, | ||
> = PrimitiveTypeLookup<TAbiType, TAbiParameterKind>[TAbiType] | ||
> = TAbiType extends SolidityBytes | ||
? // If PrimitiveTypeLookup is missing key values from AbiType, | ||
// there will be an error on this property access | ||
PrimitiveTypeLookup[TAbiType][TAbiParameterKind] | ||
: PrimitiveTypeLookup[TAbiType] | ||
// Using a map to look up types is faster, than nested conditional types | ||
// s/o https://twitter.com/SeaRyanC/status/1538971176357113858 | ||
type PrimitiveTypeLookup< | ||
TAbiType extends AbiType, | ||
TAbiParameterKind extends AbiParameterKind = AbiParameterKind, | ||
> = { | ||
[_ in SolidityAddress]: ResolvedRegister['AddressType'] | ||
} & { | ||
[_ in SolidityBool]: boolean | ||
} & { | ||
[_ in SolidityBytes]: ResolvedRegister['BytesType'][TAbiParameterKind] | ||
} & { | ||
[_ in SolidityFunction]: `${ResolvedRegister['AddressType']}${string}` | ||
} & { | ||
[_ in SolidityInt]: TAbiType extends `${'u' | ''}int${infer TBits}` | ||
? TBits extends keyof BitsTypeLookup | ||
? BitsTypeLookup[TBits] | ||
: Error<'Unknown bits value.'> | ||
: Error<`Unknown 'SolidityInt' format.`> | ||
} & { | ||
[_ in SolidityString]: string | ||
} & { | ||
[_ in SolidityTuple]: Record<string, unknown> | ||
} & { | ||
[_ in SolidityArray]: readonly unknown[] | ||
interface PrimitiveTypeLookup | ||
extends SolidityIntMap, | ||
SolidityByteMap, | ||
SolidityArrayMap { | ||
address: ResolvedRegister['AddressType'] | ||
bool: boolean | ||
function: `${ResolvedRegister['AddressType']}${string}` | ||
string: string | ||
tuple: Record<string, unknown> | ||
} | ||
type GreaterThan48Bits = Exclude<MBits, 8 | 16 | 24 | 32 | 40 | 48 | ''> | ||
type LessThanOrEqualTo48Bits = Exclude<MBits, GreaterThan48Bits | ''> | ||
type NoBits = Exclude<MBits, GreaterThan48Bits | LessThanOrEqualTo48Bits> | ||
type SolidityIntMap = { | ||
[_ in SolidityInt]: _ extends `${ | ||
| 'u' | ||
| ''}int${infer TBits extends keyof BitsTypeLookup}` | ||
? BitsTypeLookup[TBits] | ||
: never | ||
} | ||
type SolidityByteMap = { | ||
[_ in SolidityBytes]: ResolvedRegister['BytesType'] | ||
} | ||
type SolidityArrayMap = { [_ in SolidityArray]: readonly unknown[] } | ||
type GreaterThan48Bits = Exclude<MBits, 8 | 16 | 24 | 32 | 40 | 48 | NoBits> | ||
type LessThanOrEqualTo48Bits = Exclude<MBits, GreaterThan48Bits | NoBits> | ||
type NoBits = '' | ||
type BitsTypeLookup = { | ||
[_ in `${LessThanOrEqualTo48Bits}`]: ResolvedRegister['IntType'] | ||
} & { | ||
[_ in `${GreaterThan48Bits}`]: ResolvedRegister['BigIntType'] | ||
} & { | ||
[_ in NoBits]: ResolvedRegister['BigIntType'] | ||
[K in MBits]: ResolvedRegister[K extends LessThanOrEqualTo48Bits | ||
? 'IntType' | ||
: 'BigIntType'] | ||
} | ||
@@ -89,7 +86,4 @@ | ||
TAbiParameterKind extends AbiParameterKind = AbiParameterKind, | ||
> = TAbiParameter['type'] extends Exclude< | ||
// 1. Check to see if type is basic (not tuple or array) and can be looked up immediately. | ||
AbiType, | ||
SolidityTuple | SolidityArray | ||
> | ||
> = TAbiParameter['type'] extends AbiBasicType | ||
? AbiTypeToPrimitiveType<TAbiParameter['type'], TAbiParameterKind> | ||
@@ -101,60 +95,9 @@ : // 2. Check if type is tuple and covert each component | ||
} | ||
? TComponents extends readonly [] | ||
? [] | ||
: _HasUnnamedAbiParameter<TComponents> extends true | ||
? // Has unnamed tuple parameters so return as array | ||
readonly [ | ||
...{ | ||
[K in keyof TComponents]: AbiParameterToPrimitiveType< | ||
TComponents[K], | ||
TAbiParameterKind | ||
> | ||
}, | ||
] | ||
: // All tuple parameters are named so return as object | ||
{ | ||
[Component in | ||
TComponents[number] as Component extends { | ||
name: string | ||
} | ||
? Component['name'] | ||
: never]: AbiParameterToPrimitiveType<Component, TAbiParameterKind> | ||
} | ||
? AbiComponentsToPrimitiveType<TComponents, TAbiParameterKind> | ||
: // 3. Check if type is array. | ||
/** | ||
* First, infer `Head` against a known size type (either fixed-length array value or `""`). | ||
* | ||
* | Input | Head | | ||
* | --------------- | ------------ | | ||
* | `string[]` | `string` | | ||
* | `string[][][3]` | `string[][]` | | ||
*/ | ||
TAbiParameter['type'] extends `${infer Head}[${ | ||
| '' | ||
| `${SolidityFixedArrayRange}`}]` | ||
? /** | ||
* Then, infer in the opposite direction, using the known `Head` to infer the exact `Size` value. | ||
* | ||
* | Input | Size | | ||
* | ------------ | ---- | | ||
* | `${Head}[]` | `""` | | ||
* | `${Head}[3]` | `3` | | ||
*/ | ||
TAbiParameter['type'] extends `${Head}[${infer Size}]` | ||
? // Check if size is within range for fixed-length arrays, if so create a tuple. | ||
// Otherwise, create an array. Tuples and arrays are created with `[${Size}]` popped off the end | ||
// and passed back into the function to continue reduing down to the basic types found in Step 1. | ||
Size extends keyof SolidityFixedArraySizeLookup | ||
? Tuple< | ||
AbiParameterToPrimitiveType< | ||
Merge<TAbiParameter, { type: Head }>, | ||
TAbiParameterKind | ||
>, | ||
SolidityFixedArraySizeLookup[Size] | ||
> | ||
: readonly AbiParameterToPrimitiveType< | ||
Merge<TAbiParameter, { type: Head }>, | ||
TAbiParameterKind | ||
>[] | ||
: never | ||
MaybeExtractArrayParameterType<TAbiParameter['type']> extends [ | ||
infer Head extends string, | ||
infer Size, | ||
] | ||
? AbiArrayToPrimitiveType<TAbiParameter, TAbiParameterKind, Head, Size> | ||
: // 4. If type is not basic, tuple, or array, we don't know what the type is. | ||
@@ -164,5 +107,3 @@ // This can happen when a fixed-length array is out of range (`Size` doesn't exist in `SolidityFixedArraySizeLookup`), | ||
ResolvedRegister['StrictAbiType'] extends true | ||
? TAbiParameter['type'] extends infer TAbiType extends string | ||
? Error<`Unknown type '${TAbiType}'.`> | ||
: never | ||
? Error<`Unknown type '${TAbiParameter['type'] & string}'.`> | ||
: // 5. If we've gotten this far, let's check for errors in tuple components. | ||
@@ -174,15 +115,74 @@ // (Happens for recursive tuple typed data types.) | ||
// TODO: Speed up by returning immediately as soon as named parameter is found. | ||
type _HasUnnamedAbiParameter<TAbiParameters extends readonly AbiParameter[]> = | ||
TAbiParameters extends readonly [ | ||
infer Head extends AbiParameter, | ||
...infer Tail extends readonly AbiParameter[], | ||
] | ||
? Head extends { name: string } | ||
? Head['name'] extends '' | ||
? true | ||
: _HasUnnamedAbiParameter<Tail> | ||
: true | ||
: false | ||
type AbiBasicType = Exclude<AbiType, SolidityTuple | SolidityArray> | ||
type AbiComponentsToPrimitiveType< | ||
Components extends readonly AbiParameter[], | ||
TAbiParameterKind extends AbiParameterKind, | ||
> = Components extends readonly [] | ||
? [] | ||
: // Compare the original set of names to a "validated" | ||
// set where each name is coerced to a string and undefined|"" are excluded | ||
Components[number]['name'] extends Exclude< | ||
Components[number]['name'] & string, | ||
undefined | '' | ||
> | ||
? // If all the original names are present, all tuple parameters are named so return as object | ||
{ | ||
[Component in | ||
Components[number] as Component['name'] & {}]: AbiParameterToPrimitiveType< | ||
Component, | ||
TAbiParameterKind | ||
> | ||
} | ||
: // Otherwise, has unnamed tuple parameters so return as array | ||
{ | ||
[I in keyof Components]: AbiParameterToPrimitiveType< | ||
Components[I], | ||
TAbiParameterKind | ||
> | ||
} | ||
type MaybeExtractArrayParameterType<T> = | ||
/** | ||
* First, infer `Head` against a known size type (either fixed-length array value or `""`). | ||
* | ||
* | Input | Head | | ||
* | --------------- | ------------ | | ||
* | `string[]` | `string` | | ||
* | `string[][][3]` | `string[][]` | | ||
*/ | ||
T extends `${infer Head}[${'' | `${SolidityFixedArrayRange}`}]` | ||
? // * Then, infer in the opposite direction, using the known `Head` to infer the exact `Size` value. | ||
// * | ||
// * | Input | Size | | ||
// * | ------------ | ---- | | ||
// * | `${Head}[]` | `""` | | ||
// * | `${Head}[3]` | `3` | | ||
// */ | ||
T extends `${Head}[${infer Size}]` | ||
? [Head, Size] | ||
: undefined | ||
: undefined | ||
type AbiArrayToPrimitiveType< | ||
TAbiParameter extends AbiParameter | { name: string; type: unknown }, | ||
TAbiParameterKind extends AbiParameterKind, | ||
Head extends string, | ||
Size, | ||
> = Size extends keyof SolidityFixedArraySizeLookup | ||
? // Check if size is within range for fixed-length arrays, if so create a tuple. | ||
Tuple< | ||
AbiParameterToPrimitiveType< | ||
Merge<TAbiParameter, { type: Head }>, | ||
TAbiParameterKind | ||
>, | ||
SolidityFixedArraySizeLookup[Size] | ||
> | ||
: // Otherwise, create an array. Tuples and arrays are created with `[${Size}]` popped off the end | ||
// and passed back into the function to continue reducing down to the basic types found in Step 1. | ||
readonly AbiParameterToPrimitiveType< | ||
Merge<TAbiParameter, { type: Head }>, | ||
TAbiParameterKind | ||
>[] | ||
/** | ||
@@ -406,3 +406,4 @@ * Converts array of {@link AbiParameter} to corresponding TypeScript primitive types. | ||
} | ||
} | ||
// Ensure the result is "Prettied" | ||
} & unknown | ||
@@ -409,0 +410,0 @@ type _TypedDataParametersToAbiParameters< |
@@ -1,1 +0,1 @@ | ||
export const version = '0.0.0-canary.20231201T171022' | ||
export const version = '0.0.0-canary.20240117T190425' |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1156020
23897