首页 > 解决方案 > 如何在 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
}

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

标签: javascriptreactjstypescripttypescript-genericsreact-typescript

解决方案


如果您想在方法名称与状态属性名称匹配的特定情况下进行严格的类型检查,您可以使用模板文字类型和映射类型as子句。这需要 Typescript 4.1 或更高版本。

一般要点是获取状态键(在这种情况下name),并将它们映射到setName具有正确签名()的相应方法名称( (state: State, value: string) => void)。

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;
    }
  }
};

推荐阅读