Mobx 结合 TypeScript 实现 setState 类型推导

2,006次阅读
没有评论

共计 1689 个字符,预计需要花费 5 分钟才能阅读完成。

场景

mobx 中,使用 @observable 定义的 state,修改时需要借助 @action 包装才能修改,在变量比较多的情况下,十分不便,这时可以封装一个类似 React 里的 setState 方法,统一修改,在结合 TypeScript 类型推导,可以实现代码联想功能。

使用 TS 遍历指定对象,并形成一个新的类型声明

由于 Mobx Store 本质是一个 object 对象,所以需要声明一个可以遍历某个对象的方法,这里还需要排除 function,我只是需要赋值 mobx 管理的 state 即可,具体代码如下:

type GetStoreState> = {[Key in keyof T as T[Key] extends Function ? never : Key]: T[Key];
};

以上代码分解:

  1. 使用 type 声明一个 TS 工具方法,接收一个泛型 T extends Record,并为泛型缩窄类型,指定类型为可 索引类型
  2. [Key in keyof T as T[Key] extends Function ? never : Key] 分两步理解:
    • Key in keyof T 代表 key 属于传入对象的某一个属性;
    • as T[Key] extends Function ? never : Key 代表一个 js 里的三元表达式,T[Key] extends Function 代表当前遍历的属性值如果为 function 则返回 never,否则返回当前遍历的 key;
  3. T[Key] 代表遍历当前对象的属性值。

具体使用场景示例

Mobx 结合 TypeScript 实现 setState 类型推导

完整代码展示

import {action, observable} from 'mobx';

type MenuItemType = {
  id: string;
  content: string;
};

export type GetStoreState> = {[Key in keyof T as T[Key] extends Function ? never : Key]: T[Key];
};

type State = Partial>;

class BaseStore {
  /** 标题 */
  @observable title = '';

  /** 副标题 */
  @observable subTitle = '';

  /** 菜单列表 */
  @observable menuList: MenuItemType[] = [];

  /**
   * 统一更新数据
   * @param params 需要更新的数据
   * @param callback 更新后的回调方法
   */
  @action
  setState = (params: State, callback?: () => void) => {Object.keys(params).forEach((key) => {if (key in this) {(this[key as keyof this] as unknown) = params[key as keyof State];
      }
    });
    callback?.();};

  /**
   * 示例方法
   */
  init = () => {
    this.setState({title: '我是标题',});
  };
}

export default BaseStore;

扩展使用

一个项目中,会存在很多个 store,避免代码冗余,可以将此 store 封装,做基础 store,其他使用场景,统一继承,具体实现:

class BaseStore> {
  /**
   * 统一更新数据
   * @param params 需要更新的数据
   * @param callback 更新后的回调方法
   */
  setState = (params: GetStoreState>, callback?: () => void) => {Object.keys(params).forEach((key) => {if (key in this) {(this[key as keyof this] as unknown) =
          params[key as keyof GetStoreState>];
      }
    });
    callback?.();};
}

class ExampleStore extends BaseStore {pageInfo: Record = {};

  init = () => {
    this.setState({
      pageInfo: {title: 2,},
    });
  };
}

相关链接

文章来源: Mobx 结合 TypeScript 实现 setState 类型推导

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-13发表,共计1689字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)