Skip to content

Commit c145796

Browse files
committed
fix(accounts-controller): try to workaround compiler error for recursive type
1 parent 354d814 commit c145796

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

packages/accounts-controller/src/AccountsController.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import type { WritableDraft } from 'immer/dist/internal.js';
4040
import { cloneDeep } from 'lodash';
4141

4242
import type { MultichainNetworkControllerNetworkDidChangeEvent } from './types';
43+
import type { AccountsControllerStrictState } from './typing';
4344
import type { HdSnapKeyringAccount } from './utils';
4445
import {
4546
getEvmDerivationPathForIndex,
@@ -604,7 +605,8 @@ export class AccountsController extends BaseController<
604605
}
605606

606607
this.#update((state) => {
607-
state.internalAccounts.accounts = internalAccounts;
608+
(state as AccountsControllerStrictState).internalAccounts.accounts =
609+
internalAccounts;
608610
});
609611
}
610612

@@ -615,9 +617,11 @@ export class AccountsController extends BaseController<
615617
*/
616618
loadBackup(backup: AccountsControllerState): void {
617619
if (backup.internalAccounts) {
618-
this.update((currentState) => {
619-
currentState.internalAccounts = backup.internalAccounts;
620-
});
620+
this.update(
621+
(currentState: WritableDraft<AccountsControllerStrictState>) => {
622+
currentState.internalAccounts = backup.internalAccounts;
623+
},
624+
);
621625
}
622626
}
623627

@@ -906,13 +910,20 @@ export class AccountsController extends BaseController<
906910
*
907911
* @param callback - Callback for updating state, passed a draft state object.
908912
*/
909-
#update(callback: (state: WritableDraft<AccountsControllerState>) => void) {
913+
#update(
914+
callback: (state: WritableDraft<AccountsControllerStrictState>) => void,
915+
) {
910916
// The currently selected account might get deleted during the update, so keep track
911917
// of it before doing any change.
912918
const previouslySelectedAccount =
913919
this.state.internalAccounts.selectedAccount;
914920

915-
this.update((state) => {
921+
this.update((draft: WritableDraft<AccountsControllerState>) => {
922+
// By-passing recursive-type issue. We have other type-assertion that checks that both
923+
// types are compatible.
924+
const state = draft as WritableDraft<AccountsControllerStrictState>;
925+
926+
// We're casting this type to avoid having this same error in every `#update` calls.
916927
callback(state);
917928

918929
// If the account no longer exists (or none is selected), we need to re-select another one.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import type { KeyringAccountEntropyOptions } from '@metamask/keyring-api';
2+
import type { InternalAccount } from '@metamask/keyring-internal-api';
3+
4+
import type { AccountsControllerState } from './AccountsController';
5+
6+
/**
7+
* Type constraint to ensure a type is compatible with {@link AccountsControllerState}.
8+
* If the constraint is not matching, this type will resolve to `never` and thus, fails
9+
* to compile.
10+
*/
11+
type IsAccountControllerState<Type extends AccountsControllerState> = Type;
12+
13+
/**
14+
* A type compatible with {@link InternalAccount} which removes any use of recursive-type.
15+
*/
16+
export type StrictInternalAccount = Omit<InternalAccount, 'options'> & {
17+
// Use stricter options, which are relying on `Json` (which sometimes
18+
// cause compiler errors because of instanciation "too deep".
19+
// In anyway, we should rarely have to use those "untyped" options.
20+
options: {
21+
entropy?: KeyringAccountEntropyOptions;
22+
};
23+
};
24+
25+
/**
26+
* A type compatible with {@link AccountControllerState} which can be used to
27+
* avoid recursive-type issue with `internalAccounts`.
28+
*/
29+
export type AccountsControllerStrictState = IsAccountControllerState<{
30+
internalAccounts: {
31+
accounts: Record<InternalAccount['id'], StrictInternalAccount>;
32+
selectedAccount: InternalAccount['id'];
33+
};
34+
}>;

0 commit comments

Comments
 (0)