Skip to content

Instantly share code, notes, and snippets.

@nickarthur
Forked from Y2017/TS_01_start.ts
Created April 29, 2018 03:45
Show Gist options
  • Save nickarthur/8443ae75e14ef962bcadb78227fc655f to your computer and use it in GitHub Desktop.
Save nickarthur/8443ae75e14ef962bcadb78227fc655f to your computer and use it in GitHub Desktop.
Typescript
// Install the TypeScript transpiler using npm:
$ npm install -g typescript
// Then use tsc to manually compile a TypeScript source file into ES5:
$ tsc test.ts
$ node test.js
// Since TypeScript@1.8.2, tsc has a default rule for --module option: target === 'ES6' ? 'ES6' : 'commonjs' (more details can be found here), so we can simply run:
$ tsc ./a.ts ./b.ts
// For Angular 2 projects there are a number of specific settings that need to be configured in a project's
tsconfig.json
// webpack's ts-loader will do the transpilation during the build:
webpack.config.js
// TYPINGS
// -------
// typescript definition
// TypeScript recognizes files labelled *.d.ts as definition files.
// These files are meant to use TypeScript to describe interfaces presented by JavaScript libraries.
*.d.ts
//In TypeScript 2.0, users can get type files directly from @types through npm
npm install --save @types/lodash
// TSLINT ****
// ------
// Webpack can run tslint before it attempts to run tsc.
npm install --save-dev tslint-loader
// webpack.config.js
module: {
preLoaders: [
{ test: /\.ts$/, loader: 'tslint' }
],
loaders: [
{ test: /\.ts$/, loader: 'ts', exclude: /node_modules/ },
// ...
]
// ...
}
// Starter with SystemJS
https://plnkr.co/edit/kVqEKf?p=preview
Types (strongly typed, enums, any, void)
Optional parameters
Type inference
Interfaces
Shapes
// TYPES
// -----
// JavaScript's types also exist in TypeScript:
boolean (true/false)
number integers, floats, Infinity and NaN
string characters and strings of characters
[] Arrays of other types, like number[] or boolean[]
{} Object literal
undefined not set
// TypeScript also adds
enum enumerations like { Red, Blue, Green }
any use any type
void nothing
let isDone: boolean = false;
let height: number = 6;
let name: string = "bob";
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
// Types in functions :
// ----------------
// optional parameters in functions
function logMessage(message: string, isDebug?: boolean) {
if (isDebug) {
console.log('Debug: ' + message);
} else {
console.log(message);
}
}
logMessage('hi'); // 'hi'
logMessage('test', true); // 'Debug: test'
// Types in CLASSES
// ----------------
// TypeScript also treats classes as their own type:
class Foo { foo: number; }
class Bar { bar: string; }
class Baz {
constructor(foo: Foo, bar: Bar) { }
}
let baz = new Baz(new Foo(), new Bar()); // valid
baz = new Baz(new Bar(), new Foo()); // tsc errors
// optional members in classes
class Person {
name: string;
nickName?: string;
}
// INTERFACES
// ----------
// A interface is a way to define a contract on a function with respect to the arguments and their type
// It only defines the 'signature' or shape of an API
// Along with functions, an interface can also be used with a Class as well to define custom types.
// During transpilation, an interface will not generate any code, it is only used by Typescript for type checking during development.
interface Callback {
(error: Error, data: any): void;
}
function callServer(callback: Callback) {
callback(null, 'hi');
}
callServer((error, data) => console.log(data)); // 'hi'
callServer('hi'); // tsc error
// JavaScript functions can accept multiple types as well as varying arguments, that is, they can have different call signatures. Interfaces can be used to specify this.
interface PrintOutput {
(message: string): void; // common case
(message: string[]): void; // less common case
}
let printOut: PrintOutput = (message) => {
if (Array.isArray(message)) {
console.log(message.join(', '));
} else {
console.log(message);
}
}
printOut('hello'); // 'hello'
printOut(['hi', 'bye']); // 'hi, bye'
// an interface describing an object literal:
interface Action {
type: string;
}
let a: Action = {
type: 'literal'
}
// TypeScript only really cares that objects have the same shape
// if two objects have the same attributes, with the same typings, those two objects are considered to be of the same type
interface Action {
type: string;
}
let a: Action = {
type: 'literal'
}
class NotAnAction {
type: string;
constructor() {
this.type = 'Constructor function (class)';
}
}
a = new NotAnAction(); // valid TypeScript!
// DECORATORS
// ----------
// Property decorator
// -------------------
function ReadOnly(target: any, key: string) {
Object.defineProperty(target, key, { writable: false });
}
class Test {
@ReadOnly // notice there are no `()`
name: string;
}
const t = new Test();
t.name = 'jan';
console.log(t.name); // 'undefined'
// Class decorator
// ---------------
function log(prefix?: string) {
return (target) => {
// save a reference to the original constructor
var original = target;
// a utility function to generate instances of a class
function construct(constructor, args) {
var c: any = function () {
return constructor.apply(this, args);
}
c.prototype = constructor.prototype;
return new c();
}
// the new constructor behavior
var f: any = function (...args) {
console.log(prefix + original.name);
return construct(original, args);
}
// copy prototype so instanceof operator still works
f.prototype = original.prototype;
// return new constructor (will override original)
return f;
};
}
@log('hello')
class World {
}
const w = new World(); // outputs "helloWorld"
// Parameter Decorator
// -------------------
function logPosition(target: any, propertyKey: string, parameterIndex: number) {
console.log(parameterIndex);
}
class Cow {
say(b: string, @logPosition c: boolean) {
console.log(b);
}
}
new Cow().say('hello', false); // outputs 1 (newline) hello
// app/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { MyAppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(MyAppModule);
// If you're making use of Ahead-of-Time (AoT) compilation, you would code main.ts as follows.
import { platformBrowser} from '@angular/platform-browser';
import { MyAppModuleNgFactory } from '../aot/app/app.module.ngfactory';
platformBrowser().bootstrapModuleFactory(MyAppModuleNgFactory);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment