TypeScript
wagmi is designed to be as type-safe as possible! Things to keep in mind:
- Types currently require using TypeScript v4.7.4 or greater.
- Changes to types in this repository are considered non-breaking and are usually released as patch semver changes (otherwise every type enhancement would be a major version!).
- It is highly recommended that you lock your
wagmi
package version to a specific patch release and upgrade with the expectation that types may be fixed or upgraded between any release. - The non-type-related public API of wagmi still follows semver very strictly.
To ensure everything works correctly, make sure that your tsconfig.json
has strict
mode set to true:
{
"compilerOptions": {
"strict": true
}
}
Type Inference
wagmi can infer types based on ABI and EIP-712 Typed Data definitions (powered by ABIType), giving you full end-to-end type-safety from your contracts to your frontend and incredible developer experience (e.g. autocomplete ABI function names and catch misspellings, type ABI function arguments, etc.).
For this to work, you must either add const assertions to specific configuration parameters (more info on those below) or define them inline. For example, useContractRead
's abi
configuration parameter:
const { data } = useContractRead({
abi: […], // <--- defined inline
})
const abi = […] as const // <--- const assertion
const { data } = useContractRead({ abi })
If type inference isn't working, it's likely you forgot to add a const
assertion or define the configuration parameter inline.
Unfortunately TypeScript doesn't support importing JSON as
const. Check out
@wagmi/cli
to help with this! It can automatically fetchi ABIs from
Etherscan, resolve ABIs from your Foundry/Hardhat projects, generate React
Hooks, and much more.
Contract ABIs
The following hooks support type inference when you add a const assertion to abi
:
- useContract
- useContractEvent
- useContractRead
- useContractReads
- useContractWrite
- usePrepareContractWrite
- useContractInfiniteReads (must also add const assertion to
args
sinceabi
is in the return type)
For example, useContractRead
:
import { useContractRead } from 'wagmi'
const { data } = useContractRead({
// ^? const data: BigNumber | undefined
address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1',
abi: [
{
name: 'getUncleanliness',
inputs: [],
outputs: [{ name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
name: 'love',
inputs: [{ name: '', type: 'address' }],
outputs: [{ name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
name: 'play',
inputs: [],
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'love',
// ^? (property) functionName?: "getUncleanliness" | "love" | undefined
// Notice how "play" is not included since it is not a "read" function
args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'],
// ^? (property) args?: readonly [`0x${string}`] | undefined
onSuccess(data) {
// ^? (parameter) data: BigNumber
},
// Type inference flows to other configuration parameters as well:
// - select?: ((data: BigNumber) => BigNumber) | undefined
// - onSettled?: ((data: BigNumber | undefined, error: Error | null) => void) | undefined
// - …
})
EIP-712 Typed Data
Adding a const assertion to types
adds type inference to useSignTypedData
's value
configuration parameter:
import { useSignTypedData } from 'wagmi'
const result = useSignTypedData({
domain: {
name: 'Ether Mail',
version: '1',
chainId: 1,
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
},
types: {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' },
],
Mail: [
{ name: 'from', type: 'Person' },
{ name: 'to', type: 'Person' },
{ name: 'contents', type: 'string' },
],
},
value: {
// ^? (parameter) value?: { name: string; wallet: `0x${string}` } | {
// from: {
// name: string;
// wallet: `0x${string}`;
// };
// to: {
// name: string;
// wallet: `0x${string}`;
// };
// contents: string;
// } | undefined
from: {
name: 'Cow',
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
},
to: {
name: 'Bob',
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
},
contents: 'Hello, Bob!',
},
})
Configuring Internal Types
For advanced use-cases, you may want to configure wagmi's internal types. Most of wagmi's types relating to ABIs and EIP-712 Typed Data are powered by ABIType. See ABIType's documentation for more info on how to configure types.