Javascript 类型脚本:接口多态性问题

Javascript 类型脚本:接口多态性问题,javascript,typescript,oop,Javascript,Typescript,Oop,我有一个基本帐户界面: 接口帐户{ id:编号; 电子邮件:字符串; 密码:字符串; 类型:AccountType; } 其中AccountType: enum AccountType{ Foo='Foo', Bar='Bar' } 以及扩展account接口的两个帐户子类型(FooAccount和BarAccount): 接口FooAccount扩展帐户{ 富:富,; } 接口BarAccount扩展帐户{ 酒吧:酒吧; } Account是一个聚合,它保存基本帐户信息,并根据类型拥有

我有一个基本帐户界面:

接口帐户{
id:编号;
电子邮件:字符串;
密码:字符串;
类型:AccountType;
}
其中AccountType:

enum AccountType{
Foo='Foo',
Bar='Bar'
}
以及扩展account接口的两个帐户子类型(FooAccount和BarAccount):

接口FooAccount扩展帐户{
富:富,;
}
接口BarAccount扩展帐户{
酒吧:酒吧;
}
Account是一个聚合,它保存基本帐户信息,并根据类型拥有一个Foo或Bar对象

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

我已定义AccountRepository:

导出接口AccountRepository{
findById(accountId:number):账户;
}
其中,
findById(accountId:number)
返回一个帐户,但该帐户可以是任何FooAccount或BarAccount

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

  • 将使用
    findById(accountId:number)
    检索帐户
  • 检查帐户的AccountType,在本例中为
    account.type===AccountType.Foo
  • 如果AccountType检查正确,则将访问
    account.foo.id
    ,并使用该
    fooId
    执行所需的更新
这里的问题是,最后一点失败了:as
findById(accountId:number):Account
返回一个帐户,并且在其接口中没有定义
foo:foo
属性

我也尝试过以下方法,但也无法做到:

const fooccount:fooccount=findById(accountId)

因为函数返回一个帐户


我正试图弄明白如何才能做到这一点,我错过了什么?有什么我可能做错的吗

最好的解决方案可能是使用有区别的联合

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
}

使用类型断言解决了这个问题,只需将
添加为fooccount
,如下所示:

const fooccount:fooccount=findById(accountId)作为fooccount

没有必要修改现有的设计来实现它

基本上,如果S是T的子类型或T是S的子类型,则从类型S到T的断言将成功

更多信息: