来自包含函数的对象的函数生成器,函数名是键值是函数体

Posted

技术标签:

【中文标题】来自包含函数的对象的函数生成器,函数名是键值是函数体【英文标题】:Function Generator from object that contain functions , function name is by key value is the function body 【发布时间】:2021-12-27 01:35:10 【问题描述】:

我的代码:

import 
  createAction
 from '@reduxjs/toolkit'

const myFunctions = 
  f1: (payload: number) => (
    payload,
  ),
  f2: (payload: string) => (
    payload,
  ),
  f3: () => (),


type TFunctions<Obj> = 
  [Prop in keyof Obj]: Obj[Prop]

const functionGenerator = <_, T>(prefix: string, fObj: T): TFunctions<T> => 
  const returnFunctions: any = 
  Object.keys(fObj).map(key => 
    returnFunctions[key] = createAction(`$prefix/$key`, fObj[key]) // error
  )
  return returnFunctions;


export const myFunction = functionGenerator(PREFIX, myFunctions)
myFunction.f1(123)
sagaActions.f1.type // type is string of `$prefix/$key`
myFunction.f2('text')
sagaActions.f2.type // type is string of `$prefix/$key`
myFunction.f3()

export const sagaActions = functionGenerator(ADMIN, myFunctions)

从技术上讲,这段代码可以工作,但我找不到正确的打字稿来删除这个错误。 我是打字稿的初学者

错误:

1: createAction 第二个参数 Element 隐式具有“any”类型,因为“string”类型的表达式不能用于索引“unknown”类型。

2: Array.prototype.map() 需要箭头函数的返回值。(array-callback-return)

3 : 类型 '(payload: number) => payload: number; 上不存在属性 'type' '。

从 1 2 我可以忽略我会尝试找到一些解决方案或在文件中设置忽略所有错误,但 3 它在其他文件上使用时很关键,我无法理解 [Prop in keyof Obj] 中的方式:Obj[ Prop] 我将类型值添加为字符串

4: ReturnType自动检测不起作用

Playground

【问题讨论】:

请edit您的问题包含您所询问的错误文本,而不仅仅是文本图片。 对不起,下次我会明确我认为的代码的具体问题,因为这里没有工具可以显示问题是什么,图片会显示它 至于问题,您正在使用map 的副作用;只需使用结果。 return Object.keys(fObj)).map(key =&gt; createAction($prefix/$key,fObj[key])); 或者,如果您真的希望它成为一个对象,请使用fromEntriesreturn Object.fromEntries(Object.keys(fObj).map(key =&gt; [key, createAction($prefix/$key,fObj[key])])) 这样可以解决错误 2。您没有显示 createAction 并且其他错误取决于该功能,因此无法提供帮助。 import createAction from '@reduxjs/toolkit' createAction 这个reduxjs函数 【参考方案1】:

我认为sagaActions 不是这个问题的一部分,因此我将忽略它们。

首先,根据我的经验,如果您想在map 循环内改变累加器对象,最好使用[].reduce

如果你想获得createAction函数的返回类型 - 你应该参考ActionCreatorWithPreparedPayload类型

如果你想推断prefix 参数的文字类型,你应该为此创建额外的泛型。 考虑这个非常简单的例子:const foo=&lt;Prefix&gt;(prefix:Prefix)=&gt;null。 如果您对函数参数的推断感兴趣,可以查看我的article。

完整代码:

import  createAction, ActionCreatorWithPreparedPayload  from '@reduxjs/toolkit'

const myFunctions = 
  f1: (payload: number) => (
    payload,
  ),
  f2: (payload: string) => (
    payload,
  ),
  f3: () => (),


type Reducer<
  Obj extends Record<string, (...args: any[]) =>  payload: any >,
  Prefix extends string
  > = 
    [Prop in keyof Obj]:
    ActionCreatorWithPreparedPayload<
      Parameters<Obj[Prop]>,
      ReturnType<Obj[Prop]>['payload'],
      `$Prefix/$Prop & string`
    >
  

const functionGenerator = <
  Prefix extends string,
  T extends Record<string, (...args: any[]) => any>
>(prefix: Prefix, fObj: T) =>
  (Object.keys(fObj) as Array<keyof T>).reduce((acc, elem) => (
    ...acc,
    [elem]: createAction(`$prefix/$elem`, fObj[elem])
  ),  as Reducer<T, Prefix>)

export const myFunction = functionGenerator('#foo', myFunctions)
myFunction.f1(123).type // "#foo/f1"
myFunction.f2('text').type //"#foo/f2"
myFunction.f3().type // "#foo/f3"

Playground

Reducer - 遍历 Obj 键并从 ActionCreatorWithPreparedPayload 创建适当的值类型。这是您在 functionGenerator 中所做操作的一对一表示,因为 functionGenerator 遍历所有键并为每个键分配 createAction 返回值。


ActionCreatorWithPreparedPayload 泛型参数的描述:

export interface ActionCreatorWithPreparedPayload<
  Args extends unknown[],    // list of arguments
  P,                         // payload object
  T extends string = string, // prefix
  E = never,
  M = never
> extends BaseActionCreator<P, T, M, E> 
  /**
   * Calling this @link redux#ActionCreator with `Args` will return
   * an Action with a payload of type `P` and (depending on the `PrepareAction`
   * method used) a `meta`- and `error` property of types `M` and `E` respectively.
   */
  (...args: Args): PayloadAction<P, T, M, E>

【讨论】:

哇,谢谢!在我发布了我的污垢修复后,我看到了你的代码,现在我将重写我的代码! 我尝试自己理解,但找不到任何解决方案:type TF1 = ReturnType WebStorm don't see f1 , f2 , f3 in myFunction it do auto complete on type TF12 = typeof myFunction.f1 @Vasa 请提供可重现的错误示例 我尝试过去链接到 Playground,它说它“太长了 378 个字符”我带你去 Playground 并在末尾添加 type TF1 = ReturnType&lt;typeof myFunction.f1&gt; 它没有让我通过 Shortener 链接:/

以上是关于来自包含函数的对象的函数生成器,函数名是键值是函数体的主要内容,如果未能解决你的问题,请参考以下文章

来自键值对象的打字稿类型函数

EasyUI笔记Base基础

lua表中增加函数,没有指定键值,对应键值是什么

lua表中增加函数,没有指定键值,对应键值是什么

lua表中增加函数,没有指定键值,对应键值是什么

vue数据绑定原理