Problem
Constructor controllers currently raise a type error when instantiated with a messenger that was defined with an incomplete list of internal actions/events, but fail to raise that error if either the Action or Event type union of the messenger's parent ControllerMessenger doesn't contain any of the controller's internal actions/events.
Repro
/** * 1. Controller constructor erroneously accepts messenger if one or more of its internal message lists are "empty" *//* A. Both internal message lists are empty */constemptyInternalMessageListsControllerMessenger=newControllerMessenger<// `TokenRatesControllerGetStateAction` is the only member of `TokenRatesControllerActions`Exclude<TokenRatesControllerActions,TokenRatesControllerGetStateAction>|TokenRatesControllerAllowedActions,// `TokenRatesControllerStateChangeEvent` is the only member of `TokenRatesControllerEvents`Exclude<TokenRatesControllerEvents,TokenRatesControllerStateChangeEvent>|TokenRatesControllerAllowedEvents>()newTokenRatesController({messenger: emptyInternalMessageListsControllerMessenger.getRestricted({name: 'TokenRatesController',allowedActions: ['TokensController:getState','NetworkController:getNetworkClientById','NetworkController:getState','AccountsController:getAccount','AccountsController:getSelectedAccount',],allowedEvents: ['TokensController:stateChange','NetworkController:stateChange','AccountsController:selectedEvmAccountChange'],}),tokenPricesService: buildMockTokenPricesService(),})/* B. Only one internal message list is empty */constemptyInternalMessageListControllerMessenger=newControllerMessenger<TokenRatesControllerActions|TokenRatesControllerAllowedActions,// `TokenRatesControllerStateChangeEvent` is the only member of `TokenRatesControllerEvents`Exclude<TokenRatesControllerEvents,TokenRatesControllerStateChangeEvent>|TokenRatesControllerAllowedEvents>()newTokenRatesController({messenger: emptyInternalMessageListControllerMessenger.getRestricted({name: 'TokenRatesController',allowedActions: ['TokensController:getState','NetworkController:getNetworkClientById','NetworkController:getState','AccountsController:getAccount','AccountsController:getSelectedAccount',],allowedEvents: ['TokensController:stateChange','NetworkController:stateChange','AccountsController:selectedEvmAccountChange'],}),tokenPricesService: buildMockTokenPricesService(),})// Argument of type '"TokenRatesController:getState"' is not assignable to parameter of type// '"TokensController:getState" | "NetworkController:getNetworkClientById" | "NetworkController:getState" |// "AccountsController:getAccount" | "AccountsController:getSelectedAccount"'.(2345)emptyInternalMessageListsControllerMessenger.call('TokenRatesController:getState')emptyInternalMessageListsControllerMessenger.call('NetworkController:getState')// Argument of type '"TokenRatesController:stateChange"' is not assignable to parameter of type// '"TokensController:stateChange" | "NetworkController:stateChange" | "AccountsController:selectedEvmAccountChange"'.(2345)emptyInternalMessageListControllerMessenger.subscribe('TokenRatesController:stateChange',[])/** * 2. Controller constructor raises error when passed messenger with "incomplete" internal message lists */constincompleteInternalMessageListControllerMessenger=newControllerMessenger<|Extract<AccountsControllerActions,|AccountsControllerGetAccountAction|AccountsControllerGetSelectedAccountAction>|AccountsControllerAllowedActions,|Extract<AccountsControllerEvents,AccountsControllerSelectedEvmAccountChangeEvent>|AccountsControllerAllowedEvents>()newAccountsController({// Type 'ControllerMessenger<AccountsControllerGetAccountAction | AccountsControllerGetSelectedAccountAction// | AccountsControllerAllowedActions, AccountsControllerSelectedEvmAccountChangeEvent | AccountsControllerAllowedEvents>'// is not assignable to type 'AccountsControllerMessenger'.// Property '#private' in type 'ControllerMessenger' refers to a different member// that cannot be accessed from within type 'RestrictedControllerMessenger'.(2322)// AccountsController.d.ts(102, 9): The expected type comes from property 'messenger'// which is declared here on type '{ messenger: AccountsControllerMessenger; state: AccountsControllerState; }'messenger: incompleteInternalMessageListControllerMessenger,state: {internalAccounts: {accounts: {},selectedAccount: '',},},})playground link
Acceptance Criteria
Controllers inheriting from BaseControllerV2 must raise a type and/or runtime error if they are initialized with a messenger that is derived from an unrestricted ControllerMessenger that does not contain any of the controller's internal actions and/or events.
References
Problem
Constructor controllers currently raise a type error when instantiated with a messenger that was defined with an incomplete list of internal actions/events, but fail to raise that error if either the
ActionorEventtype union of the messenger's parentControllerMessengerdoesn't contain any of the controller's internal actions/events.Repro
Acceptance Criteria
Controllers inheriting from
BaseControllerV2must raise a type and/or runtime error if they are initialized with a messenger that is derived from an unrestrictedControllerMessengerthat does not contain any of the controller's internal actions and/or events.References