1- import { Contract , ContractFactory , Signer , utils } from 'ethers' ;
1+ import { BaseContract , Contract , ContractFactory , Signer , utils } from 'ethers' ;
22import type { JsonFragment } from '@ethersproject/abi' ;
33
44import DoppelgangerContract from './Doppelganger.json' ;
@@ -13,9 +13,9 @@ interface StubInterface {
1313 withArgs ( ...args : any [ ] ) : StubInterface ;
1414}
1515
16- export interface MockContract extends Contract {
16+ export interface MockContract < T extends BaseContract = BaseContract > extends Contract {
1717 mock : {
18- [ key : string ] : StubInterface ;
18+ [ key in ( ( keyof T [ 'functions' ] | 'receive' ) ) ] : StubInterface ;
1919 } ;
2020 call ( contract : Contract , functionName : string , ...params : any [ ] ) : Promise < any > ;
2121 staticcall ( contract : Contract , functionName : string , ...params : any [ ] ) : Promise < any > ;
@@ -155,7 +155,7 @@ async function deploy(signer: Signer, options?: DeployOptions) {
155155 return factory . deploy ( ) ;
156156}
157157
158- function createMock ( abi : ABI , mockContractInstance : Contract ) {
158+ function createMock < T extends BaseContract > ( abi : ABI , mockContractInstance : Contract ) : MockContract < T > [ 'mock' ] {
159159 const { functions} = new utils . Interface ( abi ) ;
160160 const encoder = new utils . AbiCoder ( ) ;
161161
@@ -166,9 +166,9 @@ function createMock(abi: ABI, mockContractInstance: Contract) {
166166 [ func . name ] : stubbed ,
167167 [ func . format ( ) ] : stubbed
168168 } ;
169- } , { } as MockContract [ 'mock' ] ) ;
169+ } , { } as MockContract < T > [ 'mock' ] ) ;
170170
171- mockedAbi . receive = {
171+ ( mockedAbi as any ) . receive = {
172172 returns : ( ) => { throw new Error ( 'Receive function return is not implemented.' ) ; } ,
173173 withArgs : ( ) => { throw new Error ( 'Receive function return is not implemented.' ) ; } ,
174174 reverts : ( ) => mockContractInstance . __waffle__receiveReverts ( 'Mock Revert' ) ,
@@ -178,11 +178,15 @@ function createMock(abi: ABI, mockContractInstance: Contract) {
178178 return mockedAbi ;
179179}
180180
181- export async function deployMockContract ( signer : Signer , abi : ABI , options ?: DeployOptions ) : Promise < MockContract > {
181+ export async function deployMockContract < T extends BaseContract = BaseContract > (
182+ signer : Signer ,
183+ abi : ABI ,
184+ options ?: DeployOptions
185+ ) : Promise < MockContract < T > > {
182186 const mockContractInstance = await deploy ( signer , options ) ;
183187
184- const mock = createMock ( abi , mockContractInstance ) ;
185- const mockedContract = new Contract ( mockContractInstance . address , abi , signer ) as MockContract ;
188+ const mock = createMock < T > ( abi , mockContractInstance ) ;
189+ const mockedContract = new Contract ( mockContractInstance . address , abi , signer ) as MockContract < T > ;
186190 mockedContract . mock = mock ;
187191
188192 const encoder = new utils . AbiCoder ( ) ;
0 commit comments