wagmi-development
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWagmi Development
Wagmi开发
Full-stack patterns for adding Wagmi features. This skill covers Viem-based actions only (not Wagmi config actions).
添加Wagmi功能的全栈模式。本技能仅涵盖基于Viem的操作(不包括Wagmi配置操作)。
Layer Overview
层级概述
- Core Action () - Base functionality wrapping Viem
packages/core/src/actions/ - Query Options () - TanStack Query integration
packages/core/src/query/ - Framework Bindings - React (), Vue (
packages/react/src/hooks/)packages/vue/src/composables/
- 核心操作()- 封装Viem的基础功能
packages/core/src/actions/ - 查询选项()- TanStack Query集成
packages/core/src/query/ - 框架绑定 - React()、Vue(
packages/react/src/hooks/)packages/vue/src/composables/
1. Core Action
1. 核心操作
Structure
结构
ts
import {
type MyActionErrorType as viem_MyActionErrorType,
type MyActionParameters as viem_MyActionParameters,
type MyActionReturnType as viem_MyActionReturnType,
myAction as viem_myAction,
} from 'viem/actions'
import type { Config } from '../createConfig.js'
import type { ChainIdParameter, ConnectorParameter } from '../types/properties.js'
import type { Compute } from '../types/utils.js'
import { getAction } from '../utils/getAction.js'
export type MyActionParameters<config extends Config = Config> = Compute<
ChainIdParameter<config> & viem_MyActionParameters
>
export type MyActionReturnType = viem_MyActionReturnType
export type MyActionErrorType = viem_MyActionErrorType
/** https://wagmi.sh/core/api/actions/myAction */
export async function myAction<config extends Config>(
config: config,
parameters: MyActionParameters<config>,
): Promise<MyActionReturnType> {
const { chainId, ...rest } = parameters
const client = config.getClient({ chainId })
const action = getAction(client, viem_myAction, 'myAction')
return action(rest)
}ts
import {
type MyActionErrorType as viem_MyActionErrorType,
type MyActionParameters as viem_MyActionParameters,
type MyActionReturnType as viem_MyActionReturnType,
myAction as viem_myAction,
} from 'viem/actions'
import type { Config } from '../createConfig.js'
import type { ChainIdParameter, ConnectorParameter } from '../types/properties.js'
import type { Compute } from '../types/utils.js'
import { getAction } from '../utils/getAction.js'
export type MyActionParameters<config extends Config = Config> = Compute<
ChainIdParameter<config> & viem_MyActionParameters
>
export type MyActionReturnType = viem_MyActionReturnType
export type MyActionErrorType = viem_MyActionErrorType
/** https://wagmi.sh/core/api/actions/myAction */
export async function myAction<config extends Config>(
config: config,
parameters: MyActionParameters<config>,
): Promise<MyActionReturnType> {
const { chainId, ...rest } = parameters
const client = config.getClient({ chainId })
const action = getAction(client, viem_myAction, 'myAction')
return action(rest)
}Key Rules
关键规则
- Viem imports: Prefix with (e.g.,
viem_)viem_getBalance - Client access:
- Read-only:
config.getClient({ chainId }) - Wallet:
await getConnectorClient(config, { chainId, connector, account }) - Mixed: Use for account,
getConnectorClientfor action (seegetClient)estimateGas.ts
- Read-only:
- Parameters: Add always. Add
ChainIdParameter<config>for wallet actions.ConnectorParameter - Type params: Mirror Viem's type params for inference. Use modifier for literal inference (abi, args).
const - Spread: Omit wagmi-specific props (,
chainId) when calling Viem action.connector
- Viem导入:添加前缀(例如:
viem_)viem_getBalance - 客户端访问:
- 只读:
config.getClient({ chainId }) - 钱包:
await getConnectorClient(config, { chainId, connector, account }) - 混合:对于账户使用,对于操作使用
getConnectorClient(参考getClient)estimateGas.ts
- 只读:
- 参数:始终添加。钱包操作需添加
ChainIdParameter<config>ConnectorParameter - 类型参数:镜像Viem的类型参数以实现类型推断。对字面量推断使用修饰符(如abi、args)
const - 展开操作:调用Viem操作时,省略Wagmi特定的属性(、
chainId)connector
Testing
测试
Runtime tests ():
action.test.tsts
import { abi, address, config } from '@wagmi/test'
import { expect, test } from 'vitest'
import { myAction } from './myAction.js'
test('default', async () => {
await expect(myAction(config, { /* required params */ })).resolves.toMatchInlineSnapshot(`...`)
})
test('parameters: chainId', async () => { /* test chainId param */ })
test('behavior: error case', async () => { /* test error handling */ })Type tests () - only if action has type inference:
action.test-d.tsts
import { config } from '@wagmi/test'
import { expectTypeOf, test } from 'vitest'
import { myAction } from './myAction.js'
test('default', async () => {
const result = await myAction(config, { /* params */ })
expectTypeOf(result).toEqualTypeOf<ExpectedType>()
})Type benchmarks () - only if action has type inference:
action.bench-d.tsts
import { attest } from '@ark/attest'
import { test } from 'vitest'
import type { MyActionParameters } from './myAction.js'
test('default', () => {
type Result = MyActionParameters<typeof abi.erc20, 'balanceOf'>
const res = {} as Result
attest.instantiations([12345, 'instantiations'])
attest(res.args).type.toString.snap(`readonly [account: \`0x\${string}\`]`)
})Wallet action tests: Connect before, disconnect after:
ts
test('default', async () => {
await connect(config, { connector })
await expect(myAction(config, { /* params */ })).resolves.toMatchInlineSnapshot(`...`)
await disconnect(config, { connector })
})运行时测试():
action.test.tsts
import { abi, address, config } from '@wagmi/test'
import { expect, test } from 'vitest'
import { myAction } from './myAction.js'
test('default', async () => {
await expect(myAction(config, { /* required params */ })).resolves.toMatchInlineSnapshot(`...`)
})
test('parameters: chainId', async () => { /* test chainId param */ })
test('behavior: error case', async () => { /* test error handling */ })类型测试()- 仅当操作存在类型推断时需要:
action.test-d.tsts
import { config } from '@wagmi/test'
import { expectTypeOf, test } from 'vitest'
import { myAction } from './myAction.js'
test('default', async () => {
const result = await myAction(config, { /* params */ })
expectTypeOf(result).toEqualTypeOf<ExpectedType>()
})类型基准测试()- 仅当操作存在类型推断时需要:
action.bench-d.tsts
import { attest } from '@ark/attest'
import { test } from 'vitest'
import type { MyActionParameters } from './myAction.js'
test('default', () => {
type Result = MyActionParameters<typeof abi.erc20, 'balanceOf'>
const res = {} as Result
attest.instantiations([12345, 'instantiations'])
attest(res.args).type.toString.snap(`readonly [account: \`0x\${string}\`]`)
})钱包操作测试:先连接,后断开:
ts
test('default', async () => {
await connect(config, { connector })
await expect(myAction(config, { /* params */ })).resolves.toMatchInlineSnapshot(`...`)
await disconnect(config, { connector })
})2. Query Options
2. 查询选项
Query (read-only) or Mutation (wallet) options for TanStack Query.
适用于TanStack Query的查询(只读)或变更(钱包)选项。
Query Structure
查询结构
ts
import {
type MyActionErrorType,
type MyActionParameters,
type MyActionReturnType,
myAction,
} from '../actions/myAction.js'
import type { Config } from '../createConfig.js'
import type { ScopeKeyParameter } from '../types/properties.js'
import type { QueryOptions, QueryParameter } from '../types/query.js'
import type { Compute, ExactPartial } from '../types/utils.js'
import { filterQueryOptions, structuralSharing } from './utils.js'
export type MyActionOptions<
config extends Config,
selectData = MyActionData,
> = Compute<ExactPartial<MyActionParameters<config>> & ScopeKeyParameter> &
QueryParameter<MyActionQueryFnData, MyActionErrorType, selectData, MyActionQueryKey<config>>
export function myActionQueryOptions<
config extends Config,
selectData = MyActionData,
>(
config: config,
options: MyActionOptions<config, selectData> = {},
): MyActionQueryOptions<config, selectData> {
return {
...options.query,
enabled: Boolean(options.requiredParam && (options.query?.enabled ?? true)),
queryFn: async (context) => {
const [, { scopeKey: _, ...parameters }] = context.queryKey
if (!parameters.requiredParam) throw new Error('requiredParam is required')
const result = await myAction(config, {
...(parameters as MyActionParameters),
requiredParam: parameters.requiredParam,
})
return result ?? null
},
queryKey: myActionQueryKey(options),
structuralSharing, // include when returning complex objects/arrays
}
}
export type MyActionQueryFnData = Compute<MyActionReturnType>
export type MyActionData = MyActionQueryFnData
export function myActionQueryKey<config extends Config>(
options: Compute<ExactPartial<MyActionParameters<config>> & ScopeKeyParameter> = {},
) {
return ['myAction', filterQueryOptions(options)] as const
}
export type MyActionQueryKey<config extends Config> = ReturnType<typeof myActionQueryKey<config>>
export type MyActionQueryOptions<
config extends Config,
selectData = MyActionData,
> = QueryOptions<MyActionQueryFnData, MyActionErrorType, selectData, MyActionQueryKey<config>>ts
import {
type MyActionErrorType,
type MyActionParameters,
type MyActionReturnType,
myAction,
} from '../actions/myAction.js'
import type { Config } from '../createConfig.js'
import type { ScopeKeyParameter } from '../types/properties.js'
import type { QueryOptions, QueryParameter } from '../types/query.js'
import type { Compute, ExactPartial } from '../types/utils.js'
import { filterQueryOptions, structuralSharing } from './utils.js'
export type MyActionOptions<
config extends Config,
selectData = MyActionData,
> = Compute<ExactPartial<MyActionParameters<config>> & ScopeKeyParameter> &
QueryParameter<MyActionQueryFnData, MyActionErrorType, selectData, MyActionQueryKey<config>>
export function myActionQueryOptions<
config extends Config,
selectData = MyActionData,
>(
config: config,
options: MyActionOptions<config, selectData> = {},
): MyActionQueryOptions<config, selectData> {
return {
...options.query,
enabled: Boolean(options.requiredParam && (options.query?.enabled ?? true)),
queryFn: async (context) => {
const [, { scopeKey: _, ...parameters }] = context.queryKey
if (!parameters.requiredParam) throw new Error('requiredParam is required')
const result = await myAction(config, {
...(parameters as MyActionParameters),
requiredParam: parameters.requiredParam,
})
return result ?? null
},
queryKey: myActionQueryKey(options),
structuralSharing, // include when returning complex objects/arrays
}
}
export type MyActionQueryFnData = Compute<MyActionReturnType>
export type MyActionData = MyActionQueryFnData
export function myActionQueryKey<config extends Config>(
options: Compute<ExactPartial<MyActionParameters<config>> & ScopeKeyParameter> = {},
) {
return ['myAction', filterQueryOptions(options)] as const
}
export type MyActionQueryKey<config extends Config> = ReturnType<typeof myActionQueryKey<config>>
export type MyActionQueryOptions<
config extends Config,
selectData = MyActionData,
> = QueryOptions<MyActionQueryFnData, MyActionErrorType, selectData, MyActionQueryKey<config>>Mutation Structure
变更结构
ts
import type { MutationOptions, MutationParameter } from '../types/query.js'
export type MyActionOptions<config extends Config, context = unknown> = MutationParameter<
MyActionData,
MyActionErrorType,
MyActionVariables<config>,
context
>
export function myActionMutationOptions<config extends Config, context>(
config: config,
options: MyActionOptions<config, context> = {},
): MyActionMutationOptions<config> {
return {
...options.mutation,
mutationFn: async (variables) => {
return myAction(config, variables)
},
mutationKey: ['myAction'],
}
}
export type MyActionMutationOptions<config extends Config> = MutationOptions<
MyActionData,
MyActionErrorType,
MyActionVariables<config>
>ts
import type { MutationOptions, MutationParameter } from '../types/query.js'
export type MyActionOptions<config extends Config, context = unknown> = MutationParameter<
MyActionData,
MyActionErrorType,
MyActionVariables<config>,
context
>
export function myActionMutationOptions<config extends Config, context>(
config: config,
options: MyActionOptions<config, context> = {},
): MyActionMutationOptions<config> {
return {
...options.mutation,
mutationFn: async (variables) => {
return myAction(config, variables)
},
mutationKey: ['myAction'],
}
}
export type MyActionMutationOptions<config extends Config> = MutationOptions<
MyActionData,
MyActionErrorType,
MyActionVariables<config>
>Key Rules
关键规则
- ExactPartial vs UnionExactPartial: Use for simple types,
ExactPartialfor complex unions (contract actions)UnionExactPartial - enabled: Based on required params being truthy
- structuralSharing: Include when action returns objects/arrays
- filterQueryOptions: Filters common non-serializable props. Skip props like manually in query key.
onReplaced - Query key: Always
['actionName', filterQueryOptions(options)]
- ExactPartial vs UnionExactPartial:简单类型使用,复杂联合类型(合约操作)使用
ExactPartialUnionExactPartial - enabled:基于必填参数是否为真值
- structuralSharing:当操作返回对象/数组时需要包含
- filterQueryOptions:过滤常见的非可序列化属性。在查询键中手动跳过等属性
onReplaced - 查询键:始终为
['actionName', filterQueryOptions(options)]
Testing
测试
ts
import { config } from '@wagmi/test'
import { expect, test } from 'vitest'
import { myActionQueryOptions } from './myAction.js'
test('default', () => {
expect(myActionQueryOptions(config, {})).toMatchInlineSnapshot(`
{
"enabled": false,
"queryFn": [Function],
"queryKey": ["myAction", {}],
}
`)
})
test('enabled', () => {
expect(myActionQueryOptions(config, { requiredParam: 'value' }).enabled).toBe(true)
})
test('queryFn: calls query fn', async () => {
const options = myActionQueryOptions(config, { requiredParam: 'value' })
const result = await options.queryFn({ queryKey: options.queryKey } as any)
expect(result).toMatchInlineSnapshot(`...`)
})ts
import { config } from '@wagmi/test'
import { expect, test } from 'vitest'
import { myActionQueryOptions } from './myAction.js'
test('default', () => {
expect(myActionQueryOptions(config, {})).toMatchInlineSnapshot(`
{
"enabled": false,
"queryFn": [Function],
"queryKey": ["myAction", {}],
}
`)
})
test('enabled', () => {
expect(myActionQueryOptions(config, { requiredParam: 'value' }).enabled).toBe(true)
})
test('queryFn: calls query fn', async () => {
const options = myActionQueryOptions(config, { requiredParam: 'value' })
const result = await options.queryFn({ queryKey: options.queryKey } as any)
expect(result).toMatchInlineSnapshot(`...`)
})3. Framework Bindings
3. 框架绑定
React Query Hook
React查询Hook
ts
'use client'
import type { Config, MyActionErrorType, ResolvedRegister } from '@wagmi/core'
import type { Compute } from '@wagmi/core/internal'
import {
type MyActionData,
type MyActionOptions,
myActionQueryOptions,
} from '@wagmi/core/query'
import type { ConfigParameter } from '../types/properties.js'
import { type UseQueryReturnType, useQuery } from '../utils/query.js'
import { useChainId } from './useChainId.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<
config extends Config = Config,
selectData = MyActionData,
> = Compute<MyActionOptions<config, selectData> & ConfigParameter<config>>
export type UseMyActionReturnType<selectData = MyActionData> =
UseQueryReturnType<selectData, MyActionErrorType>
/** https://wagmi.sh/react/api/hooks/useMyAction */
export function useMyAction<
config extends Config = ResolvedRegister['config'],
selectData = MyActionData,
>(
parameters: UseMyActionParameters<config, selectData> = {},
): UseMyActionReturnType<selectData> {
const config = useConfig(parameters)
const chainId = useChainId({ config })
const options = myActionQueryOptions(config, {
...parameters,
chainId: parameters.chainId ?? chainId,
query: parameters.query,
})
return useQuery(options)
}ts
'use client'
import type { Config, MyActionErrorType, ResolvedRegister } from '@wagmi/core'
import type { Compute } from '@wagmi/core/internal'
import {
type MyActionData,
type MyActionOptions,
myActionQueryOptions,
} from '@wagmi/core/query'
import type { ConfigParameter } from '../types/properties.js'
import { type UseQueryReturnType, useQuery } from '../utils/query.js'
import { useChainId } from './useChainId.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<
config extends Config = Config,
selectData = MyActionData,
> = Compute<MyActionOptions<config, selectData> & ConfigParameter<config>>
export type UseMyActionReturnType<selectData = MyActionData> =
UseQueryReturnType<selectData, MyActionErrorType>
/** https://wagmi.sh/react/api/hooks/useMyAction */
export function useMyAction<
config extends Config = ResolvedRegister['config'],
selectData = MyActionData,
>(
parameters: UseMyActionParameters<config, selectData> = {},
): UseMyActionReturnType<selectData> {
const config = useConfig(parameters)
const chainId = useChainId({ config })
const options = myActionQueryOptions(config, {
...parameters,
chainId: parameters.chainId ?? chainId,
query: parameters.query,
})
return useQuery(options)
}React Mutation Hook
React变更Hook
ts
'use client'
import { useMutation } from '@tanstack/react-query'
import type { Config, ResolvedRegister, MyActionErrorType } from '@wagmi/core'
import {
type MyActionData,
type MyActionMutate,
type MyActionMutateAsync,
type MyActionOptions,
type MyActionVariables,
myActionMutationOptions,
} from '@wagmi/core/query'
import type { ConfigParameter } from '../types/properties.js'
import type { UseMutationReturnType } from '../utils/query.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<config extends Config = Config, context = unknown> =
MyActionOptions<config, context> & ConfigParameter<config>
export type UseMyActionReturnType<config extends Config = Config, context = unknown> =
UseMutationReturnType<
MyActionData,
MyActionErrorType,
MyActionVariables<config>,
context,
MyActionMutate<config, context>,
MyActionMutateAsync<config, context>
>
/** https://wagmi.sh/react/api/hooks/useMyAction */
export function useMyAction<
config extends Config = ResolvedRegister['config'],
context = unknown,
>(
parameters: UseMyActionParameters<config, context> = {},
): UseMyActionReturnType<config, context> {
const config = useConfig(parameters)
const options = myActionMutationOptions(config, parameters)
const mutation = useMutation(options)
type Return = UseMyActionReturnType<config, context>
return {
...mutation,
mutate: mutation.mutate as Return['mutate'],
mutateAsync: mutation.mutateAsync as Return['mutateAsync'],
}
}ts
'use client'
import { useMutation } from '@tanstack/react-query'
import type { Config, ResolvedRegister, MyActionErrorType } from '@wagmi/core'
import {
type MyActionData,
type MyActionMutate,
type MyActionMutateAsync,
type MyActionOptions,
type MyActionVariables,
myActionMutationOptions,
} from '@wagmi/core/query'
import type { ConfigParameter } from '../types/properties.js'
import type { UseMutationReturnType } from '../utils/query.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<config extends Config = Config, context = unknown> =
MyActionOptions<config, context> & ConfigParameter<config>
export type UseMyActionReturnType<config extends Config = Config, context = unknown> =
UseMutationReturnType<
MyActionData,
MyActionErrorType,
MyActionVariables<config>,
context,
MyActionMutate<config, context>,
MyActionMutateAsync<config, context>
>
/** https://wagmi.sh/react/api/hooks/useMyAction */
export function useMyAction<
config extends Config = ResolvedRegister['config'],
context = unknown,
>(
parameters: UseMyActionParameters<config, context> = {},
): UseMyActionReturnType<config, context> {
const config = useConfig(parameters)
const options = myActionMutationOptions(config, parameters)
const mutation = useMutation(options)
type Return = UseMyActionReturnType<config, context>
return {
...mutation,
mutate: mutation.mutate as Return['mutate'],
mutateAsync: mutation.mutateAsync as Return['mutateAsync'],
}
}Vue Composable (Query)
Vue组合式函数(查询)
ts
import type { Config, MyActionErrorType, ResolvedRegister } from '@wagmi/core'
import type { Compute } from '@wagmi/core/internal'
import {
type MyActionData,
type MyActionOptions,
myActionQueryOptions,
} from '@wagmi/core/query'
import { computed } from 'vue'
import type { ConfigParameter } from '../types/properties.js'
import type { DeepMaybeRef } from '../types/ref.js'
import { deepUnref } from '../utils/cloneDeep.js'
import { type UseQueryReturnType, useQuery } from '../utils/query.js'
import { useChainId } from './useChainId.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<
config extends Config = Config,
selectData = MyActionData,
> = Compute<DeepMaybeRef<MyActionOptions<config, selectData> & ConfigParameter<config>>>
export type UseMyActionReturnType<selectData = MyActionData> =
UseQueryReturnType<selectData, MyActionErrorType>
/** https://wagmi.sh/vue/api/composables/useMyAction */
export function useMyAction<
config extends Config = ResolvedRegister['config'],
selectData = MyActionData,
>(
parameters: UseMyActionParameters<config, selectData> = {},
): UseMyActionReturnType<selectData> {
const params = computed(() => deepUnref(parameters))
const config = useConfig(params)
const chainId = useChainId({ config })
const options = computed(() =>
myActionQueryOptions(config as any, {
...params.value,
chainId: params.value.chainId ?? chainId.value,
query: params.value.query,
}),
)
return useQuery(options as any) as any
}ts
import type { Config, MyActionErrorType, ResolvedRegister } from '@wagmi/core'
import type { Compute } from '@wagmi/core/internal'
import {
type MyActionData,
type MyActionOptions,
myActionQueryOptions,
} from '@wagmi/core/query'
import { computed } from 'vue'
import type { ConfigParameter } from '../types/properties.js'
import type { DeepMaybeRef } from '../types/ref.js'
import { deepUnref } from '../utils/cloneDeep.js'
import { type UseQueryReturnType, useQuery } from '../utils/query.js'
import { useChainId } from './useChainId.js'
import { useConfig } from './useConfig.js'
export type UseMyActionParameters<
config extends Config = Config,
selectData = MyActionData,
> = Compute<DeepMaybeRef<MyActionOptions<config, selectData> & ConfigParameter<config>>>
export type UseMyActionReturnType<selectData = MyActionData> =
UseQueryReturnType<selectData, MyActionErrorType>
/** https://wagmi.sh/vue/api/composables/useMyAction */
export function useMyAction<
config extends Config = ResolvedRegister['config'],
selectData = MyActionData,
>(
parameters: UseMyActionParameters<config, selectData> = {},
): UseMyActionReturnType<selectData> {
const params = computed(() => deepUnref(parameters))
const config = useConfig(params)
const chainId = useChainId({ config })
const options = computed(() =>
myActionQueryOptions(config as any, {
...params.value,
chainId: params.value.chainId ?? chainId.value,
query: params.value.query,
}),
)
return useQuery(options as any) as any
}Framework Rules
框架规则
| Rule | React | Vue |
|---|---|---|
| Top directive | | None |
| Parameters wrapper | | |
| Reactivity | Direct | |
| Doc URL | | |
Shared rules:
- : Use in function signature only, not type defs
ResolvedRegister['config'] - No /
enabledin hooks: Handled by queryOptionsstructuralSharing
| 规则 | React | Vue |
|---|---|---|
| 顶部指令 | | 无 |
| 参数包装 | | |
| 响应式处理 | 直接处理 | |
| 文档链接 | | |
共享规则:
- :仅在函数签名中使用,不要在类型定义中使用
ResolvedRegister['config'] - Hooks中无需设置/
enabled:由queryOptions处理structuralSharing
Testing
测试
Query hook test-d.ts:
ts
import { abi } from '@wagmi/test'
import { expectTypeOf, test } from 'vitest'
import { useMyAction } from './useMyAction.js'
test('select data', () => {
const result = useMyAction({
/* params */
query: {
select(data) {
expectTypeOf(data).toEqualTypeOf<ExpectedDataType>()
return data
},
},
})
expectTypeOf(result.data).toEqualTypeOf<ExpectedDataType>()
})Mutation hook test-d.ts:
ts
import { expectTypeOf, test } from 'vitest'
import { useMyAction } from './useMyAction.js'
test('context', () => {
const { mutate } = useMyAction({
mutation: {
onMutate(variables) {
expectTypeOf(variables).toMatchTypeOf<{ /* expected shape */ }>()
return { foo: 'bar' }
},
onError(error, variables, context) { /* test types */ },
onSuccess(data, variables, context) { /* test types */ },
onSettled(data, error, variables, context) { /* test types */ },
},
})
mutate({ /* params */ }, {
onSuccess(data, variables, context) { /* test inference */ },
})
})查询Hook类型测试():
test-d.tsts
import { abi } from '@wagmi/test'
import { expectTypeOf, test } from 'vitest'
import { useMyAction } from './useMyAction.js'
test('select data', () => {
const result = useMyAction({
/* params */
query: {
select(data) {
expectTypeOf(data).toEqualTypeOf<ExpectedDataType>()
return data
},
},
})
expectTypeOf(result.data).toEqualTypeOf<ExpectedDataType>()
})变更Hook类型测试():
test-d.tsts
import { expectTypeOf, test } from 'vitest'
import { useMyAction } from './useMyAction.js'
test('context', () => {
const { mutate } = useMyAction({
mutation: {
onMutate(variables) {
expectTypeOf(variables).toMatchTypeOf<{ /* expected shape */ }>()
return { foo: 'bar' }
},
onError(error, variables, context) { /* test types */ },
onSuccess(data, variables, context) { /* test types */ },
onSettled(data, error, variables, context) { /* test types */ },
},
})
mutate({ /* params */ }, {
onSuccess(data, variables, context) { /* test inference */ },
})
})Exports
导出
Add to in respective package:
exports/index.tsts
// packages/core/src/exports/index.ts
export {
type MyActionParameters,
type MyActionReturnType,
type MyActionErrorType,
myAction,
} from '../actions/myAction.js'
// packages/core/src/exports/query.ts
export {
type MyActionData,
type MyActionOptions,
type MyActionQueryFnData,
type MyActionQueryKey,
type MyActionQueryOptions,
myActionQueryKey,
myActionQueryOptions,
} from '../query/myAction.js'
// packages/react/src/exports/index.ts
export {
type UseMyActionParameters,
type UseMyActionReturnType,
useMyAction,
} from '../hooks/useMyAction.js'在对应包的中添加导出:
exports/index.tsts
// packages/core/src/exports/index.ts
export {
type MyActionParameters,
type MyActionReturnType,
type MyActionErrorType,
myAction,
} from '../actions/myAction.js'
// packages/core/src/exports/query.ts
export {
type MyActionData,
type MyActionOptions,
type MyActionQueryFnData,
type MyActionQueryKey,
type MyActionQueryOptions,
myActionQueryKey,
myActionQueryOptions,
} from '../query/myAction.js'
// packages/react/src/exports/index.ts
export {
type UseMyActionParameters,
type UseMyActionReturnType,
useMyAction,
} from '../hooks/useMyAction.js'Verification
验证
bash
undefinedbash
undefinedFormat
格式化
pnpm format
pnpm format
Type check (all or filtered)
类型检查(全部或筛选)
pnpm check:types
pnpm --filter @wagmi/core check:types
pnpm --filter wagmi check:types
pnpm check:types
pnpm --filter @wagmi/core check:types
pnpm --filter wagmi check:types
Test (all or filtered)
测试(全部或筛选)
pnpm test
pnpm test --project core
pnpm test --project react
pnpm test
pnpm test --project core
pnpm test --project react
Update test snapshots
更新测试快照
pnpm vitest -u
pnpm vitest -u
Type benchmarks
类型基准测试
pnpm bench:types
pnpm bench:types
Viem version mismatch in test snapshots
测试快照中Viem版本不匹配
pnpm version:update:viem
pnpm version:update:viem
Build (all or filtered)
构建(全部或筛选)
pnpm run clean && pnpm build
pnpm --filter @wagmi/core build
undefinedpnpm run clean && pnpm build
pnpm --filter @wagmi/core build
undefined