Skip to content Skip to sidebar Skip to footer

TypeScript: Interface Polymorphism Issue

I have a base Account interface: interface Account { id: number; email: string; password: string; type: AccountType; } where AccountType: enum AccountType { Foo = 'foo',

Solution 1:

The best solution is probably to use a discriminated union.

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
}

Solution 2:

Solved this using Type Assertion, by just adding as FooAccount like this:

const fooAccount: FooAccount = findById(accountId) as FooAccount;

There's no need to modify the existing design to achieve it.

Basically, the assertion from type S to T succeeds if either S is a subtype of T or T is a subtype of S.

More info: https://basarat.gitbooks.io/typescript/docs/types/type-assertion.html


Post a Comment for "TypeScript: Interface Polymorphism Issue"