Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit d3baae6

Browse files
authored
Fix Contract methods input param type any[] (#7340)
* fix types * fix * Update type.test.ts * fix tests * fix test
1 parent 0681f97 commit d3baae6

File tree

6 files changed

+96
-6
lines changed

6 files changed

+96
-6
lines changed

packages/web3-eth-contract/src/contract.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ type ContractBoundMethod<
127127
Abi extends AbiFunctionFragment,
128128
Method extends ContractMethod<Abi> = ContractMethod<Abi>,
129129
> = (
130-
...args: Method['Inputs'] extends undefined | unknown ? any[] : Method['Inputs']
130+
...args: Abi extends undefined
131+
? any[]
132+
: Method['Inputs'] extends never
133+
? any[]
134+
: Method['Inputs']
131135
) => Method['Abi']['stateMutability'] extends 'payable' | 'pure'
132136
? PayableMethodObject<Method['Inputs'], Method['Outputs']>
133137
: NonPayableMethodObject<Method['Inputs'], Method['Outputs']>;

packages/web3-eth-contract/test/fixtures/erc20.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { ContractEventOptions, PayableMethodObject, NonPayableMethodObject } fro
2222
export interface Erc20Interface {
2323
methods: {
2424
[key: string]: (
25-
...args: ReadonlyArray<any>
25+
...args: any[]
2626
) =>
2727
| PayableMethodObject<ReadonlyArray<unknown>, ReadonlyArray<unknown>>
2828
| NonPayableMethodObject<ReadonlyArray<unknown>, ReadonlyArray<unknown>>;

packages/web3-eth-contract/test/integration/local_account/contract_overloaded_methods.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,14 @@ describe('contract ERC721 overloaded functions', () => {
102102
});
103103

104104
it('transferFrom with 3 invalid arguments', () => {
105-
expect(() => contractDeployed.methods.safeTransferFrom(1, 2, 3)).toThrow('Web3 validator');
105+
expect(() => contractDeployed.methods.safeTransferFrom('1', '2', 3)).toThrow(
106+
'Web3 validator',
107+
);
106108
});
107109

108110
it('transferFrom with 2 arguments', () => {
109111
expect(() =>
112+
// @ts-expect-error invalid arguments so ts will throw an error
110113
contractDeployed.methods.safeTransferFrom(localAccount.address, localAccount.address),
111114
).toThrow('Web3 validator');
112115
});

packages/web3-eth-contract/test/unit/contract_typing.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ describe('contract typing', () => {
3737
]);
3838

3939
typecheck('should allow any input params', () => [
40-
expectTypeOf<Parameters<typeof defaultContractInstance.methods.test>>().toBe<any[]>(),
41-
expectTypeOf<Parameters<typeof web3ContractInstance.methods.test>>().toBe<any[]>(),
40+
expectTypeOf<Parameters<typeof defaultContractInstance.methods.test>>().toBe<
41+
any[] | []
42+
>(),
43+
expectTypeOf<Parameters<typeof web3ContractInstance.methods.test>>().toBe<any[] | []>(),
4244
]);
4345
});
4446
describe('custom abi', () => {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
This file is part of web3.js.
3+
4+
web3.js is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU Lesser General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
web3.js is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public License
15+
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
import { Contract } from '../../src';
19+
20+
describe('Contract method types', () => {
21+
it('contract method params types test', () => {
22+
const abiAsConst = [
23+
{
24+
inputs: [
25+
{ internalType: 'uint256', name: 'testArg1', type: 'uint256' },
26+
{ internalType: 'uint256', name: 'testArg2', type: 'uint256' },
27+
],
28+
name: 'testWithParams',
29+
outputs: [{ internalType: 'uint256', name: 'testRes1', type: 'uint256' }],
30+
stateMutability: 'nonpayable',
31+
type: 'function',
32+
},
33+
{
34+
inputs: [],
35+
name: 'testWithoutParams',
36+
outputs: [{ internalType: 'uint256', name: 'testRes1', type: 'uint256' }],
37+
stateMutability: 'nonpayable',
38+
type: 'function',
39+
},
40+
] as const;
41+
42+
const abiAsArray = [
43+
{
44+
inputs: [
45+
{ internalType: 'uint256', name: 'testArg1', type: 'uint256' },
46+
{ internalType: 'uint256', name: 'testArg2', type: 'uint256' },
47+
],
48+
name: 'testWithParams',
49+
outputs: [{ internalType: 'uint256', name: 'testRes1', type: 'uint256' }],
50+
stateMutability: 'nonpayable',
51+
type: 'function',
52+
},
53+
{
54+
inputs: [],
55+
name: 'testWithoutParams',
56+
outputs: [{ internalType: 'uint256', name: 'testRes1', type: 'uint256' }],
57+
stateMutability: 'nonpayable',
58+
type: 'function',
59+
},
60+
];
61+
62+
// abi as const
63+
const contract = new Contract<typeof abiAsConst>(abiAsConst);
64+
contract.methods.testWithParams(1, 2); // no ts error - works as expected
65+
// @ts-expect-error ts compiler error
66+
expect(() => contract.methods.testWithParams()).toThrow(); // ts error - works as expected
67+
// @ts-expect-error ts compiler error
68+
contract.methods.testWithoutParams(1, 2); // ts error - works as expected
69+
contract.methods.testWithoutParams(); // no ts error - works as expected
70+
71+
// abi as usual array type
72+
const contract2 = new Contract<typeof abiAsArray>(abiAsArray);
73+
// because we do not know exact type without const or provided type
74+
contract2.methods.testWithParams(1, 2); // no ts error - works as expected
75+
contract2.methods.testWithoutParams(); // no ts error - works as expected
76+
contract2.methods.testWithoutParams(1, 2); // no ts error - works as expected
77+
expect(() => contract2.methods.testWithParams()).toThrow(); // no ts error - works as expected
78+
});
79+
});

packages/web3-types/src/eth_abi_types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,9 @@ export type ContractMethodOutputParameters<Params extends ReadonlyArray<unknown>
320320
: [];
321321

322322
export type ContractMethodInputParameters<Params extends ReadonlyArray<unknown> | undefined> =
323-
Params extends readonly []
323+
Params extends undefined
324+
? any[]
325+
: Params extends readonly []
324326
? []
325327
: Params extends readonly [infer H, ...infer R]
326328
? H extends AbiParameter

0 commit comments

Comments
 (0)