You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中实现State到StateMutationSpec的递归映射类型?

解决方案

你需要的递归类型映射实现如下:

// 核心递归映射类型
type DeepMutationSpec<T> =
  // 每个层级支持两种选择:直接传新值,或者传入变更函数
  T | StateMutator<T extends object ? DeepMutationSpecObject<T> : T>;

// 遍历对象属性递归处理
type DeepMutationSpecObject<T extends object> = {
  [K in keyof T]: DeepMutationSpec<T[K]>;
};

如果需要跳过Date、正则、函数这类特殊对象的递归展开,可以调整为兼容特殊类型的版本:

type DeepMutationSpec<T> =
  T | StateMutator<
    // 特殊类型直接返回原类型,不递归展开
    T extends Date | RegExp | Function ? T :
    T extends object ? DeepMutationSpecObject<T> :
    T
  >;

type DeepMutationSpecObject<T extends object> = {
  [K in keyof T]: DeepMutationSpec<T[K]>;
};

配套工具函数类型调整

适配类型体系的工具函数定义如下,和你的使用示例完全兼容:

// 原有的变更函数定义保持不变
type StateMutator<TState> = (state: TState) => TState;

// 调整append类型
function append<TArray extends any[]>(item: TArray[number]): StateMutator<TArray> {
  throw new Error("Not implemented")
}

// 调整patch类型
function patch<T>(spec: DeepMutationSpec<T>): StateMutator<T> {
  throw new Error("Not implemented");
}

// 调整createNextState为泛型,支持任意结构的State
function createNextState<T>(spec: DeepMutationSpec<T>, initialState: T): T {
  throw new Error("Not implemented")
}

type ItemOf<T> = T extends Array<infer TItem> ? TItem : never;

效果验证

代入你给出的State结构测试,生成的类型和你期望的StateMutationSpec完全一致:

interface State {
    a: { bs: number[], c: boolean}
}

// 用法和你的示例完全匹配,全程类型安全
const nextState: State = createNextState({
    a: patch({ bs: append(1), c: false })
}, {} as State);

内容的提问来源于stack exchange,提问作者Gregor Woiwode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:27:05