Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[base-controller] Implement utility type ControllerActionsMap for generating, storing, exposing internal action types #4583

Open
MajorLift opened this issue Aug 2, 2024 · 0 comments
Labels

Comments

@MajorLift
Copy link
Contributor

MajorLift commented Aug 2, 2024

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']

https://github.com/MetaMask/core/pull/4397/files#diff-7ada7b099f6bcc6f3d4acd71f94b604636abd22cc556a76dbe7b3e610b1d9233R90-R118

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 of AssetsContractController: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.
@MajorLift MajorLift changed the title [base-controller] Implement utility type ControllerActionsMap, which can be used to reference [base-controller] Implement utility type ControllerActionsMap for generating, storing, exposing internal action types Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant