-
Notifications
You must be signed in to change notification settings - Fork 6
TypeScript guidelines
There are two ways to export things in a TypeScript file:
You can export many things:
Things.ts:
export class Foo { ... }
export class Bar { ... }
...or you can export only one thing using the = syntax:
Foo.ts:
class Foo { ... }
export = Foo;
The difference lies in consumption. In the first, to use Foo, you'd have to load Things first, and then know that Foo is available on Things:
import Things = require('Things');
var foo = new Things.Foo();
In the second model, there is only one Foo and it is straightforward to understand how to load it:
import Foo = require('Foo');
var foo = new Foo();
We should try to adhere to one class/interface per TS file when the class or interface is expected to be used by a consumer.
For cases when a component or control needs a data structure or similar utility with a public scope, but doesn't necessarily expect a consumer to instantiate it, it is reasonable to create a module with exported types. For example:
module MyComponentUtil {
export class MyComplexReturnObject {
foo: string;
bar: number;
baz: boolean;
}
export class MyParamObject {
key: string;
bar: MyComplexReturnObject;
}
}
export = MyComponentUtil;
Interfaces should be in their own files. Interface names should be prefixed with I:
// Good (filename: IDataSource.ts)
interface IDataSource { ... }
// Bad (filename: DataSource.ts)
interface DataSource { ... }
With TypeScript 1.3 we now have protected support, which makes access modifiers (coupled with subclassing) very useful. It is recommended to use them as appropriate. However, they do not replace using underscore prefixes for protected/private things. Remember that TypeScript, and thus access modifiers, are a precompile check and that they don't translate into a consumed JavaScript library, so we still need a way to differentiate public methods from internals.