I have a base Account interface:
interface Account {
id: number;
email: string;
password: string;
type: AccountType;
}
where AccountType:
enum AccountType {
Foo = 'foo',
Bar = 'bar'
}
and two account subtypes (FooAccount and BarAccount) that extend the Account interface:
interface FooAccount extends Account {
foo: Foo;
}
interface BarAccount extends Account {
bar: Bar;
}
Account is an aggregate that holds basic account info and, depending on the type, owns a Foo or a Bar object.
Actions on these objects, can only be performed by their owners (the account).
I have defined an AccountRepository:
export interface AccountRepository {
findById(accountId: number): Account;
}
where the findById(accountId: number) returns an Account, but this account could be any FooAccount or BarAccount.
I want to use this findById function before performing any action on a Foo or Bar. For example, let's say I want to update an account's Foo:
- would use
findById(accountId: number)to retrieve the account - check the AccountType of the account, in this case
account.type === AccountType.Foo - if the AccountType check is correct, then would access
account.foo.idand use thatfooIdto perform the desired update
The problem here is, that this last point is failing: as findById(accountId: number): Account returns an Account and there is no foo: Foo property defined in its interface.
I have also tried the following, but cannot be done either:
const fooAccount: FooAccount = findById(accountId);
because the function returns an Account.
I am trying to figure out how can this be achieved, what am I missing out? Is there anything I could be doing wrong?