TypeScript:接口多态问题

2023-12-07

我有一个基地Account界面:

interface Account {
  id: number;
  email: string;
  password: string;
  type: AccountType;
}

where 帐户类型:

enum AccountType {
  Foo = 'foo',
  Bar = 'bar'
}

和两个帐户子类型(Foo账户 and 酒吧账户),延伸Account界面:

interface FooAccount extends Account {
  foo: Foo;
}
interface BarAccount extends Account {
  bar: Bar;
}

Account是保存基本帐户信息的聚合,并且根据类型,拥有Foo or a Bar目的。

对这些对象的操作只能由其所有者(帐户)执行。

我定义了一个账户信息库:

export interface AccountRepository {
  findById(accountId: number): Account;
}

哪里的findById(accountId: number)返回一个Account,但这个帐户可以是任何Foo账户 or 酒吧账户.

我想用这个findById在对 a 执行任何操作之前函数Foo or Bar。例如,假设我想更新帐户的Foo:

  • 会使用findById(accountId: number)找回帐户
  • 检查帐户的 AccountType,在本例中account.type === AccountType.Foo
  • 如果 AccountType 检查正确,则将访问account.foo.id并使用它fooId执行所需的更新

这里的问题是,最后一点失败了:findById(accountId: number): Account返回一个Account并且没有foo: Foo在其接口中定义的属性。

我也尝试过以下操作,但也无法完成:

const fooAccount: FooAccount = findById(accountId);

因为该函数返回一个Account.

我想弄清楚如何实现这一目标,我错过了什么?我可能做错了什么吗?


最好的解决方案可能是使用受歧视的联合。

export class Bar { public idBar: number; }
class Foo { public idFoo: number; }
interface AccountCommon {
  id: number;
  email: string;
  password: string;
}

enum AccountType {
  Foo = 'foo',
  Bar = 'bar'
}

interface FooAccount extends AccountCommon {
  type: AccountType.Foo; // type can only be Foo
  foo: Foo;
}
interface BarAccount extends AccountCommon {
  type: AccountType.Bar; // type can only be Bar
  bar: Bar;
}
// The discriminated union
type Account = BarAccount | FooAccount //type is common so type can be either Foo or Bar

export interface AccountRepository {
  findById(accountId: number): Account;
}

let r: AccountRepository;

let a = r.findById(0);
if (a.type === AccountType.Bar) { // type guard
  a.bar.idBar // a is now BarAccount
} else {
  a.foo.idFoo // a is now FooAccount
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeScript:接口多态问题 的相关文章

随机推荐