Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 按对象的键/值键入脚本动态函数_Javascript_Reactjs_Typescript_Factory Pattern - Fatal编程技术网

Javascript 按对象的键/值键入脚本动态函数

Javascript 按对象的键/值键入脚本动态函数,javascript,reactjs,typescript,factory-pattern,Javascript,Reactjs,Typescript,Factory Pattern,是否有一种基于初始接口设置函数的方法?我有一堆ListofFunction和等量的包含函数类型的接口。我想创建一个返回自定义钩子的工厂。这样做的目的是节省大量代码,使编辑和向所有钩子添加特性变得轻而易举 FunctionInterface是所有函数名及其返回值 listOfFunctions是一个设置函数(实际代码有一个配置),它返回一个包含函数列表的对象 chosenfunction是一个将在钩子中返回的函数,它允许我与其中一个listoff函数交互。这意味着参数(如果需要)。真正的应用程序中

是否有一种基于初始接口设置函数的方法?我有一堆ListofFunction和等量的包含函数类型的接口。我想创建一个返回自定义钩子的工厂。这样做的目的是节省大量代码,使编辑和向所有钩子添加特性变得轻而易举

FunctionInterface
是所有函数名及其返回值

listOfFunctions
是一个设置函数(实际代码有一个配置),它返回一个包含函数列表的对象

chosenfunction
是一个将在钩子中返回的函数,它允许我与其中一个listoff函数交互。这意味着参数(如果需要)。真正的应用程序中的函数是承诺,将设置钩子的状态。在本例中,我只返回一个值并设置state

A) 这是否可以使用
funcObject[funcName]()
并创建一个要用typescript调用的函数?这将需要添加或不添加参数的能力

B) 有没有办法获取函数类型的返回值?所以在这个例子中:
类型canthisweak=()=>字符串我想提取
字符串
;我们的想法不是对所有ListofFunction和FunctionInterface进行重构。有很多。如果我必须创建一个复杂的工厂,那么我觉得这样更经济

interface FunctionInterface {
  noParamsNoReturn: () => void;
  noParamsNumberReturn: () => number;
  propsAndNoReturn: (id: string) => void;
  propsAndReturn: (id: string) => string;
}

const listOfFunctions = (): FunctionInterface => {
  return {
    noParamsNoReturn: () => void,
    noParamsNumberReturn: () => 1,
    propsAndNoReturn: (id: string) => console.log(id),
    propsAndReturn: (id: string) => id,
  }
}

function runThis<T>(funcName: keyof T, funcObject: T): void {
  const [value, setValue] = React.useState();

  // Can I have typescript set up the params here?
  const theChosenFunction = ();
  const theChosenFunction = (props) => {
    // Can I have typescript invoke the function properly here?
    const result = funcObject[funcName](); // funcObject[funcName](props)
    if (result) {
       setValue(result);
    }
  }
  return {
    theChosenFunction
  }
}


const result = runThis<FunctionInterface>('noParamsNoReturn', listOfFunctions());

result.theChosenFunction()
// OR
result.theChosenFunction('someId');
接口函数接口{
noParamsNoReturn:()=>无效;
NoParamsUnberReturn:()=>编号;
propsAndNoReturn:(id:string)=>void;
propsAndReturn:(id:string)=>string;
}
const listOfFunctions=():FunctionInterface=>{
返回{
noParamsNoReturn:()=>无效,
NoParamsUnberReturn:()=>1,
propsAndNoReturn:(id:string)=>console.log(id),
propsAndReturn:(id:string)=>id,
}
}
函数runThis(funcName:keyof T,funcObject:T):void{
const[value,setValue]=React.useState();
//我可以让typescript在这里设置参数吗?
const theChosenFunction=();
const theChosenFunction=(道具)=>{
//我可以让typescript在这里正确调用函数吗?
const result=funcObject[funcName]();//funcObject[funcName](道具)
如果(结果){
设定值(结果);
}
}
返回{
中心功能
}
}
const result=runThis('noParamsNoReturn',listOfFunctions());
result.theChosenFunction()
//或
结果:CHOSENFunction('someId');
有内置类型和实用类型,它们分别采用函数类型
T
,并使用条件类型推断来提取函数类型和返回类型:

type SomeFuncType = (x: string, y: number) => boolean;
type SomeFuncParams = Parameters<SomeFuncType>; // [x: string, y: number]
type SomeFuncRet = ReturnType<SomeFuncType>; // boolean
我给函数提供了两个通用类型参数:
K
,对应于
funcName
的类型,和
F
,对应于
funcObject
的类型。
K extends PropertyKey
F extends Recordany>
保证
funcName
将是类似键的类型(
string
number
symbol
),并且
funcObject
将在该键处具有函数值属性

然后,我们可以使用
chosenfunction
来允许使用可变参数列表调用函数。因此,
(…props)=>funcObject[funcName](…props)
将接受任意数量的参数(包括零),并将它们传递给被调用的函数。TypeScript将此类参数列表表示为元组类型。因此,让
chosenfunction
的调用签名看起来像
(…props:Parameters)=>void
意味着它将接受与
funcObject
键处的
funcName
中的条目相同的参数,并且它不会输出任何东西(因为您的实现没有输出任何东西)


让我们看看它是否有效:

const result = runThis('noParamsNoReturn', listOfFunctions());
result.theChosenFunction(); // okay
result.theChosenFunction('someId'); // error! Expected 0 arguments, but got 1.

const anotherResult = runThis('propsAndReturn', listOfFunctions());
anotherResult.theChosenFunction(); // error! Expected 1 arguments, but got 0.
anotherResult.theChosenFunction("someId"); // okay

runThis(listOfFunctions(), 'someId'); // error! '
// FunctionInterface' is not assignable to 'string | number | symbol'.
runThis('foo', listOfFunctions()); // error!  
// Property 'foo' is missing in type 'FunctionInterface'

runThis(
  'bar', 
  { bar: (x: string, y: number, z: boolean) => { } }
).theChosenFunction("hey", 123, true); // okay
我觉得不错


这看起来很有希望!我将在今天晚些时候详细讨论这个问题!如果道具可以是一个对象或一个值呢?props={id:string}或props=99;如果道具=99,则无法传播。你知道怎么做吗?我不明白;参数列表是一个数组,因此在
(…props)=>
中,
props
的类型可能是
[{id:string}]
[number]
,或者,如果有多个类似
[{id:string},number]
的参数。如果你能提供你所说问题的答案,我可以看看。我明白了。你是对的。至于最小可重复性示例。这是根据我在一个私人项目上使用的代码创建的,并进行了最小程度的缩减。也许,您希望看到更多的方法示例?如果你愿意的话,我可以再举一点例子。
const result = runThis('noParamsNoReturn', listOfFunctions());
result.theChosenFunction(); // okay
result.theChosenFunction('someId'); // error! Expected 0 arguments, but got 1.

const anotherResult = runThis('propsAndReturn', listOfFunctions());
anotherResult.theChosenFunction(); // error! Expected 1 arguments, but got 0.
anotherResult.theChosenFunction("someId"); // okay

runThis(listOfFunctions(), 'someId'); // error! '
// FunctionInterface' is not assignable to 'string | number | symbol'.
runThis('foo', listOfFunctions()); // error!  
// Property 'foo' is missing in type 'FunctionInterface'

runThis(
  'bar', 
  { bar: (x: string, y: number, z: boolean) => { } }
).theChosenFunction("hey", 123, true); // okay