Open
Description
Motivation
- Currently, we manually enumerate each individual internal action type definition in controller files, and then manually enumerate them again in the type union for internal actions (example). We should have a DRY-er way of doing this.
- Most handlers for controller internal actions are simply public controller class methods bound to the controller instance.
- Instead of exporting each action separately, we could export a single "controller actions map" type that contains all internal actions, and use it to select and extract any number of its stored action types.
Proof of concept
/**
* A utility type that derives the public method names of a given messenger consumer class,
* and uses it to generate the class's internal messenger action types.
* @template Controller - A messenger consumer class.
*/
// TODO: Figure out generic constraint and move to base-controller
type ControllerActionsMap<Controller> = {
[ClassMethod in keyof PublicInterface<Controller> as Controller[ClassMethod] extends ActionConstraint['handler']
? ClassMethod
: never]: {
type: `${typeof name}:${ClassMethod & string}`;
handler: Controller[ClassMethod];
};
};
type AssetsContractControllerActionsMap =
ControllerActionsMap<AssetsContractController>;
/**
* The union of all public class method names of {@link AssetsContractController}.
*/
type AssetsContractControllerMethodName =
keyof AssetsContractControllerActionsMap;
/**
* The union of all internal messenger actions available to the {@link AssetsContractControllerMessenger}.
*/
export type AssetsContractControllerActions =
AssetsContractControllerActionsMap[AssetsContractControllerMethodName];
/*
* A single internal action type selected from the controller actions map
*/
export type AssetsContractControllerGetERC20StandardAction =
AssetsContractControllerActionsMap['getERC20Standard'];
/**
* A union of several internal types selected from the controller actions map
*/
export type AssetsContractControllerGetStandardActions =
AssetsContractControllerActionsMap['getERC20Standard' | 'getERC721Standard' | 'getERC1155Standard']
Acceptance Criteria
- MVP: Write a generic type that...
- a) Accepts a controller class.
- b) Derives its public class method names.
- c) Uses them to generate the class's internal messenger action types.
- d) Outputs a type object populated with the action types.
- e) The types are keyed with the de-namespaced action names (i.e.
getERC20Standard
instead ofAssetsContractController:getERC20Standard
).
- Stretch: Better handling for exceptions.
- a) Accepts a map of action names and handlers which are exceptions to the general rule that each class method corresponds to an action handler.
- b) Add these exceptions to the controller actions map as well.