-
Notifications
You must be signed in to change notification settings - Fork 902
Typescript Conventions (draft)
File names should follow the same conventions as JS files.
Export classes and interfaces if they should be public, i.e. consumable or assignable from other files. If they're entirely internal, do not export them.
Interface names should be prefixed with I
- not because it's pretty, but because it's the convention with Typescript.
Prefer interfaces to classes for simple objects that have only fields and no methods. It's easier to instantiate them when needed by passing a simple hash object, e.g.
public interface IAccount {
name: string;
type: string;
}
// in some class method
public isProd(account: IAccount): boolean {
return account.name === 'prod';
}
public someOtherMethod(someObject: any): boolean {
return isProd({ name: someObject.account, type: someObject.cloudProvider });
// much nicer than declaring a new instance of Account, then assigning property values, e.g.
// const account = new Account();
// account.name = someObject.account;
// account.type = someObject.cloudProvider;
// return isProd(account);
// * or *
// including a constructor in Account, then having to know what order the arguments need to be in
}
If the file contains an Angular module, export the module name as a constant in uppercase, separated by underscores. It should match the name of the object. If the object is a component or directive, append the tye of object to the module name constant. Examples: retryService
would export RETRY_SERVICE
, awsFooter
component would export AWS_FOOTER_COMPONENT
, cloudProviderRegistry
would export CLOUD_PROVIDER_REGISTRY
.
Try to keep imports organized: third-party modules, then internal modules, with a line break between different import groups e.g.
import {pluck} from 'lodash';
import {module} from 'angular';
import {API_SERVICE, Api} from 'core/api/api.service';
import SOME_MODULE_FROM_A_JS_FILE from './someLegacy.service.thatIsStillJs';
import './someStyles.less';
When importing a legacy file, i.e. a file that does a default export and has not been converted to Typescript, try to pick a module name that follows the conventions above.
As an example, consider the following file (retry.service.js):
let angular = require('angular');
module.exports = angular.module('spinnaker.deck.core.retry.service', [])
.factory('retryService', function ($q, $timeout) {
// ...
});
This file generates a default export (spinnaker.deck.core.retry.service
). When bringing this in to a TS file, we've traditionally used require
, e.g. require('core/retry/retry.service')
. Instead, import
it, assigning the default export like this:
import RETRY_SERVICE from 'core/retry/retry.service';