首页 > 其他分享 >[Typescript] Builder pattern 07- Reducer

[Typescript] Builder pattern 07- Reducer

时间:2023-05-07 16:11:47浏览次数:38  
标签:username Typescript return pattern Builder state action password type


import {Expect, Equal} from "../types/utils"
import { expect, it } from 'vitest';
type PayloadsToDiscriminatedUnion<T extends Record<string, any>> = {
    [K in keyof T]: { type: K } & T[K];
  }[keyof T];

  export class DynamicReducer<
    TState,
    TPayloadMap extends Record<string, any> = {}
  > {
    private handlers = {} as Record<
      string,
      (state: TState, payload: any) => TState
    >;

    addHandler<TType extends string, TPayload extends object>(
      type: TType,
      handler: (state: TState, payload: TPayload) => TState
    ): DynamicReducer<TState, TPayloadMap & Record<TType, TPayload>> {
      this.handlers[type] = handler;

      return this;
    }

    reduce(
      state: TState,
      action: PayloadsToDiscriminatedUnion<TPayloadMap>
    ): TState {
      const handler = this.handlers[action.type];
      if (!handler) {
        return state;
      }

      return handler(state, action);
    }
  }

  interface State {
    username: string;
    password: string;
  }

  const reducer = new DynamicReducer<State>()
    .addHandler(
      "LOG_IN",
      (state, action: { username: string; password: string }) => {
        return {
          username: action.username,
          password: action.password,
        };
      }
    )
    .addHandler("LOG_OUT", () => {
      return {
        username: "",
        password: "",
      };
    })
    .addHandler("UPDATE_USERNAME", (state, action: { username: string }) => {
      return {
        ...state,
        username: action.username,
      };
    });

  it("Should return the new state after LOG_IN", () => {
    const state = reducer.reduce(
      { username: "", password: "" },
      {
        type: "UPDATE_USERNAME",
        username: "awdawdawd",
      }
    );

    type test = [Expect<Equal<typeof state, State>>];

    expect(state).toEqual({ username: "foo", password: "bar" });
  });

  it("Should return the new state after LOG_OUT", () => {
    const state = reducer.reduce(
      { username: "foo", password: "bar" },
      { type: "LOG_OUT" }
    );

    type test = [Expect<Equal<typeof state, State>>];

    expect(state).toEqual({ username: "", password: "" });
  });

  it("Should error if you pass it an incorrect action", () => {
    const state = reducer.reduce(
      { username: "foo", password: "bar" },
      {
        // @ts-expect-error
        type: "NOT_ALLOWED",
      }
    );
  });

  it("Should error if you pass an incorrect payload", () => {
    const state = reducer.reduce(
      { username: "foo", password: "bar" },
      // @ts-expect-error
      {
        type: "LOG_IN",
      }
    );
  });

 

标签:username,Typescript,return,pattern,Builder,state,action,password,type
From: https://www.cnblogs.com/Answer1215/p/17379458.html

相关文章

  • [React Typescript] ComponentProps
    Blog:https://www.totaltypescript.com/react-component-props-type-helper GetanyProptypefromhtmlelement:import{ComponentProps}from"react";typeButtonProps=ComponentProps<"button">; GetpropstypefromaComponen......
  • 与chatGPT讨论c#的calss 与TypeScript中的calss问题
    与chatGPT讨论c#的calss与TypeScript中的calss问题目前来说chatGPT可以说是一场革命,它为我们提供了另一种选项,当你遇到问题的时候,只能去百度但度出来的结果大多不是我们想要的结果,特别是百度当你想要问度娘时......等到的却是一大堆广告,心中不由升起无明之火,不知百度能不能也搞......
  • (转)Java中的String、StringBuilder和StringBuffer
    1、StringString对象是不可变的,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。那么我们new一个String对象,比如Stringa=newString("A")Stringa2=newString("A")和直接创建一个字符串,比如Stringb="A"这两种方......
  • typescript
    什么是typescripttypescript是微软开发的编程语言,它的后缀名是ts,通过编译可以将ts文件编译成ts文件,它定义了一些新语法使得开发起来可维护性更高也更好用,ts与js的区别如下图所示:在进行angular开发时,开发者不需要引入ts依赖,angular已经导入了ts依赖。快速上手ts编译tschell......
  • typescript重写canvas --10.绘制文字2
    typescript重写canvas--10.绘制文字21.使用canvas绘制文字<!DOCTYPEHTML><html><head><metacharset="utf-8"/></head><body><canvasid="myCanvas"width="450"height="400">你的浏览器......
  • JAVA中的两个容器StringBuilder和StringJoiner概述
    JAVA中的两个容器StringBuilder和StringJoiner概述StringBuilder可以看成一个容器,创建之后里面的内容是可以修改的方法名说明publicStringBuilderappend(任意类型)添加数据,并返回对象本身publicStringBuilderreverse()反转容器中的内容publicintlength()返......
  • String、StringBuilder、StringBuffer
    String真正不可变有下面几点原因:保存字符串的数组被final修饰且为私有的,并且String类没有提供/暴露修改这个字符串的方法。String类被final修饰导致其不能被继承,进而避免了子类破坏String不可变。String:不可变,线程安全StringBuilder:可变,单线程,线程不安全StringBuf......
  • cpp: Strategy Pattern II
     //Gold.h:此文件包含"Gold"类。策略模式StrategyPatternC++14//2023年5月1日涂聚文GeovinDuVisualStudio2022edit.#pragmaonce//#ifndefGOLD_H//#defineGOLD_H#ifndef_GOLD_#define_GOLD_#include<iostream>#include<sstrea......
  • kysely typescript 类型安全的sql 查询构建包
    typescript目前已经有不少方便的sql工具了,kysely是一个类型安全方便的sql查询构建工具对于使用typescript开发node服务的是个一个不错的选择,值得试用参考资料https://github.com/kysely-org/kyselyhttps://typeorm.io/https://github.com/typeorm......
  • typescript重写canvas --9.绘制文字
    typescript重写canvas--9.绘制文字1.使用canvas绘制文字<!DOCTYPEHTML><html><head><metacharset="utf-8"/></head><body><canvasid="myCanvas"width="450"height="400">你的浏览器不支......