Ilia Choly
Ilia Choly

Reputation: 18557

TypeScript: Organizing related classes & interfaces

I'm porting a JavaScript project to TypeScript and I'm unsure how to organize related entities (types/interfaces/classes).

Below are the different approaches I'm considering.

Prefix all interfaces with class name

interface IFooOptions {}

class Foo {
  constructor(options: IFooOptions) {}
}

// usage
var foo = new Foo({});

Create a module:

module Foo {
  export interface IOptions {
    // ...
  }

  export class Foo {
    constructor(options: IOptions) {}
  }
}

// usage
var foo = new Foo.Foo({});

Create a module with factory function:

module Foo {
  export interface IOptions {
    // ...
  }

  export class Foo {
    constructor(options: IOptions) {}
  }

  export function create(options: IOptions): Foo {
    return new Foo(options);
  }
}

// usage
var foo = Foo.create({});

What are the pros/cons of these methods? Is there a convention in the community?

Upvotes: 2

Views: 1343

Answers (1)

Fenton
Fenton

Reputation: 251242

For internal modules, it would look like this:

module Foo {
  export interface FooOptions {
    // ...
  }

  export class Foo {
    constructor(options: FooOptions) {}
  }
}

// usage
var foo = new Foo.Foo({
    //...
});

The use of the I prefix on interfaces is discouraged (although it does exist in the wild).

The specificity of the interface name comes from the principle that names should be more specific the deeper you go. So you start general and get more specific, a bit like this example from C# (in C#, the I prefix is recommended for interfaces, but it is a nominal type system whereas TypeScript is structural)...

System.Data.SqlClient.SqlConnection
System.Data.FooClient.FooConnection

Note that they could have used Connection, because it is nested in SqlClient - but it actually makes you work harder to understand the code if you have to see the full namespace to know what you are dealing with.

If the interface is common between SqlClient and FooClient, this is where you see a System.Data.IConnection, which is less nested and less specific.

Upvotes: 2

Related Questions