javascript - TypeScript:接口多态性问题
问题描述
我有一个基本帐户界面:
interface Account {
id: number;
email: string;
password: string;
type: AccountType;
}
其中AccountType:
enum AccountType {
Foo = 'foo',
Bar = 'bar'
}
以及扩展Account接口的两个帐户子类型(FooAccount和BarAccount) :
interface FooAccount extends Account {
foo: Foo;
}
interface BarAccount extends Account {
bar: Bar;
}
Account是包含基本帐户信息的聚合体,并且根据类型,拥有Foo或Bar对象。
对这些对象的操作只能由其所有者(帐户)执行。
我已经定义了一个AccountRepository:
export interface AccountRepository {
findById(accountId: number): Account;
}
其中findById(accountId: number)
返回一个Account,但该帐户可以是任何FooAccount或BarAccount。
我想在对 a或findById
执行任何操作之前使用此功能。例如,假设我想更新一个帐户的:Foo
Bar
Foo
- 将用于
findById(accountId: number)
检索帐户 - 检查帐户的 AccountType,在这种情况下
account.type === AccountType.Foo
- 如果 AccountType 检查正确,则将访问
account.foo.id
并使用它fooId
来执行所需的更新
这里的问题是,最后一点失败了: asfindById(accountId: number): Account
返回一个Accountfoo: 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
}
推荐阅读
- ms-word - Word - 删除 <> 之间的文本,包括表格
- python - Python 3 - 增强 writelines 函数以始终添加新行
- javascript - 调整引导警报的大小并将“x”保持在正确的位置
- tensorflow - 如何在tensorflow中实现自定义损失函数并进行梯度反向传播
- javascript - jQuery 如果每个 li == 0 内的每个输入值
- php - 如何使用源和目的地时间计算旅行时间?
- mysql - MySQL 为 JOINed 表中的每一行提供结果
- ios - Swift:从 AppDelegate 中的 UNTextInputNotificationAction 获取内容
- java - 尝试使用 TestNG 和 WebDriverManager 运行测试时出错
- sql - 循环通过bulkcolumn SQL Server获取静态字符串之间的值