+('' + +'0xff'+ +0)+1 +[]+ +[] + {} + (0.1+0.2)
const boolyMcBoolBool: boolean = true;
const numyMcNumNum: number = 1337;
const stringyMcStrStr: string = "☃";
let anyMcAnAn: any = {};
anyMcAnAn = 1; // That's "fine".
enum Direction {
Up = 1,
Down,
Left,
Right
}
let playerDirection: Direction = Direction.Up;
let s = "foo";
s = null; // error, 'null' is not assignable to 'string'
let sn: string | null = "bar";
sn = null; // ok
sn = undefined; // not assignable to 'string | null'
// These do the same thing
let nums1: number[] = [1, 2, 3];
let nums2: Array<number> = [1, 2, 3];
+-------+
| +-+ |
| ^ | |
char *str[10];
^ ^ | |
| +---+ |
+-----------+
class Person {
constructor(public name: string) { }
}
interface Loggable {
log(): void;
}
class ConsoleLogger implements Loggable {
log() {
// Returning something would break my interface
}
}
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(): Fish | Bird {
// I can only return a Fish or a Bird
}
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U>{};
for (let id in first) {
(<any>result)[id] = (<any>first)[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<any>result)[id] = (<any>second)[id];
}
}
return result;
}
var jim = extend(new Person("Jim"), new ConsoleLogger());
type StringyNumber = string | number;
let example: StringyNumber = "hello"
example = 1 // This is actually fine.
if (pet.swim) {
pet.swim();
}
// or
if ((<Fish>pet).swim) {
(<Fish>pet).swim();
}
function stuff(param1: string, p2: string | number) {
// I accept calls like:
// stuff("", "")
// stuff("", 2)
}
interface Cloner {
clone(animal: Dog): Dog;
clone(animal: Cat): Cat;
clone(animal: Sheep): Sheep;
clone(animal: Animal): Animal;
}
function isNumber(x: any): x is number {
return typeof x === "number";
}
/*
// Compiler checks for guard violations,
// and removes them when building JS:
function isNumber(x) {
return typeof x === "number";
}
*/
function MyClassDecorator(value: string) {
return function (target: Function) {
console.log(“MyClassDecorator”, value, target);
}
}
@MyClassDecorator(“my metadata”)
class MyClass { }
var myClass = new MyClass();
function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
descriptor.value = function(...args: any[]) {
console.log("The method args are: " + JSON.stringify(args));
return result;
};
return descriptor;
}
class MyClass {
@log
myMethod(arg: string) {
return "Message -- " + arg;
}
}
function PropertyDecorator(
target: Object, // The prototype of the class
propertyKey: string | symbol // The name of the property
) {
console.log("PropertyDecorator called on: ", target, propertyKey);
}
class PropertyDecoratorExample {
@PropertyDecorator
name: string;
}
class MyClass {
myMethod(@logParam myParameter: string) {}
}
function logParam(target: any, propertyKey: string | symbol, parameterIndex: number) {
console.log(target); // MyClass prototype
console.log(propertyKey); // "myMethod"
console.log(parameterIndex); // 0
}
# How to use a JavaScript lib
npm install --save @types/lodash
import * as _ from "lodash";
_.padStart("Hello TypeScript!", 20, " ");
// In a .d.ts file or .ts file that is not a module:
declare module "SomeModule" {
export function fn(): string;
}
/// <reference path="myModules.d.ts" />
import * as m from "SomeModule";
export namespace Shapes {
export class Triangle { /* ... */ }
export class Square { /* ... */ }
}
import * as shapes from "./shapes";
// and instead of shapes.Shapes.Triangle(); without namespaces...
let t = new shapes.Triangle();