Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.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 如何推断TypeScript中的参数类型?_Javascript_Reactjs_Typescript_Typescript Generics_React Typescript - Fatal编程技术网

Javascript 如何推断TypeScript中的参数类型?

Javascript 如何推断TypeScript中的参数类型?,javascript,reactjs,typescript,typescript-generics,react-typescript,Javascript,Reactjs,Typescript,Typescript Generics,React Typescript,如何推断参数类型 我想实现一个类似于redux的状态管理库,但在定义类型时遇到了困难。 原型如下: interface IModel<S, A> { state: S action: IActions<S, A> } type IActions<S, A> = { [K in keyof A]: (state: S, payload: ???) => void // `???` How should it be defined here

如何推断参数类型

我想实现一个类似于redux的状态管理库,但在定义类型时遇到了困难。 原型如下:


interface IModel<S, A> {
  state: S
  action: IActions<S, A>
}

type IActions<S, A> =  {
  [K in keyof A]: (state: S, payload: ???) => void // `???` How should it be defined here
}

class Model<T,A> implements IModel<T,A>{
  //...
}

// examples

const model=new Model({
  state:{name:"foo"},
  action:{
    setName:(state,name: string)=>{
      //...
    },
    fetchAccount:(state,payload: {
      id: number,
      locked: boolean,
      ...
})=>{
      //...
    }
  }
})

//
let state={name:''}
model.action.setName(state,'bar') // ok
model.action.setName(state,123)   // error

接口IModel{
州:S
行动:国际行动
}
I类选项={
[K in keyof A]:(状态:S,有效负载:?)=>void/``这里应该如何定义
}
类模型实现IModel{
//...
}
//例子
常数模型=新模型({
国家:{name:“foo”},
行动:{
setName:(状态,名称:字符串)=>{
//...
},
fetchAccount:(状态,有效负载:{
身份证号码:,
锁定:布尔,
...
})=>{
//...
}
}
})
//
let state={name:'}
model.action.setName(状态为'bar')//确定
model.action.setName(state,123)//错误

如果要在方法名与状态属性名匹配的特定情况下进行严格的类型检查,可以使用。这需要Typescript 4.1或更新版本

一般要点是获取状态键(在本例中为
name
),并将它们映射到具有正确签名(
(state:state,value:string)=>void
)的相应方法名(
setName

类型操作={
[K in keyof State&字符串为`set${Capitalize}`]:(State:State,value:State[K])=>void;
}
类型模型={
国家:国家;
行动:行动;
}
常数模型:模型={
声明:{
名称:“foo”,
},
行动:{
setName(状态、值){
state.name=值;
}
}
};

TypeScript不是C#,所以请不要使用
I
作为接口的类型名称前缀。还有,您不使用的原因吗?您阅读了吗?此模型和IModel仅用于此处的问题描述,以使其更直观。实际代码根本没有IModel接口的定义。它与redux相同,但其表示和实现不同。不管怎样,谢谢你的回答。如果你说不出来,我很难回答这个问题。你的方法非常接近,但动作在一开始就不是固定的方法。方法名称和参数不受限制,参数不一定与状态匹配。我将再次修改上面的示例以使其clearer@jun您不能为任意操作设置类型安全性。在最简单的情况下,假设一个字段是字符串,另一个字段是数字,无法推断应该将哪个字段传递给任意命名的操作。这就是目前的问题,所以我只是发布帮助
type Actions<State> = {
  [K in keyof State & string as `set${Capitalize<K>}`]: (state: State, value: State[K]) => void;
}

type Model<State> = {
  state: State;
  actions: Actions<State>;
}

const model: Model<{ name: string }> = {
  state: {
    name: 'foo',
  },
  actions: {
    setName(state, value) {
      state.name = value;
    }
  }
};