介绍

typescript是javascript的超集,最终也要编译成javascript,有一定的编程基础再来看吧

编译器

安装

npm install -g tsc

配置

tsc通过项目中的tsconfig.json来配置,先来看一个demo

{
    "compilerOptions": {
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "allowUnreachableCode": true,
        "allowUnusedLabels": true,
        "alwaysStrict": true,
        "baseUrl": "../asdf.ts",
        "charset": "utf-8",
        "checkJs": true,
        "declaration": true,
        "declarationDir": "../out",
        "diagnostics": true,
        "disableSizeLimit": true,
        "emitBOM": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "extendedDiagnostics": true,
        "forceConsistentCasingInFileNames": true,
        "importHelpers": true,
        "inlineSourceMap": true,
        "inlineSources": true,
        "isolatedModules": true,
        "jsx": "preserve",
        "jsxFactory": "React.createElement",
        "lib": [
            "es2015", "es2015.collection", "es2015.symbol"
        ],
        "listEmittedFiles": true,
        "listFiles": true,
        "locale": "zh-cn",
        "mapRoot": "../out/map",
        "maxNodeModuleJsDepth": 0,
        "module": "es2015",
        "newLine": "CRLF",
        "noEmit": false,
        "noEmitHelpers"
    },
    // 指定一个包含相对或绝对文件路径的列表
    "files": [
        "core.ts",
        "sys.ts",
        "types.ts",
        "scanner.ts",
        "parser.ts",
        "utilities.ts",
        "binder.ts",
        "checker.ts",
        "emitter.ts",
        "program.ts",
        "commandLineParser.ts",
        "tsc.ts",
        "diagnosticInformationMap.generated.ts"
    ]
    // 功能类似files,指定包含的编译路径
     "include": [
         // * 匹配0或多个字符(不包括目录分隔符)
         // ? 匹配一个任意字符(不包括目录分隔符)
         //  **/ 递归匹配任意子目录
        "src/**/*"
    ],
    // 指定不包含,不用编译的路径
    "exclude": [
        "node_modules",
        "**/*.spec.ts"
    ]
}

注意:
0.
CompilerOptions可配置项
1.如果匹配*或者.*那么只会编译支持的扩展文件名[.ts,.tsx,.d.ts]如果allowJS设置为true那么还包含[.js,.jsx]
2.如果filesinclude都没有被指定,编译器默认包含当前目录和子目录下所有的TypeScript文件
3.exclude默认情况下会排除node_modules,bower_components,jspm_packages和<outDir>目录。

编译

tsc index.ts
运行
node index.js

基础

数据类型

// boolean
let isDone: boolean = false;
// number
let decLiteral: number = 6;
// stirng
let name: string = "bob";
// array
let list: number[] = [1, 2, 3];
// tuple
let x: [string, number];
// enum
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
// any
let notSure: any = 4;
notSure = "maybe a string instead";
// Void
function warnUser(): void {
    console.log("This is my warning message");
}
// null
let u: undefined = undefined;
// undefined
let n: null = null;
// never
function error(message: string): never {
    throw new Error(message);
}

function infiniteLoop(): never {
    while (true) {
    }
}
//Object:object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。
// 创建方法
declare function create(o: object | null): void;
create({asdf:1});//{asdf:1}不是以上类型

类型断言

let someValue: any = "this is a string";
// 断定someValue为string类型,所以才调用.length属性
let strLength: number = (<string>someValue).length;

let someValue: any = "this is a string";
// 另一种写法
let strLength: number = (someValue as string).length;

变量声明

//作用域不同,使用方式不同
let:比var强一点但可修改
const:常量(不可修改)
//解构
let input = [1, 2];
let [first, second] = input;

接口

基础接口

interface LabelledValue {
  // 必选属性
  label: string;
  // 可选属性
  color?: string;
  width?: number;
  readonly padding:number;
}

let asdf:LabelledValue = {label:'asdf',color:'red', padding:10}

asdf.padding = 11(出错)

函数类型接口

interface SearchFunc {
  // 成员为一个传餐带返回值的函数
  (source: string, subString: string): boolean;
}

// 使用函数接口
let mySearch: SearchFunc;
// 实现函数
mySearch = function(source: string, subString: string) {
  let result = source.search(subString);
  return result > -1;
}

可索引类型

interface StringArray {
  [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];

实现接口

interface ClockInterface {
    currentTime: Date;
}

class Clock implements ClockInterface {
    currentTime: Date;
    constructor(h: number, m: number) { }
}

继承接口

interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;

混合类型

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");

继承

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();


class Animal {
    name: string;
    constructor(theName: string) { this.name = theName; }
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 5) {
        console.log("Slithering...");
        super.move(distanceInMeters);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 45) {
        console.log("Galloping...");
        super.move(distanceInMeters);
    }
}

let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

封装

public

class Animal {
    public name: string;
    public constructor(theName: string) { this.name = theName; }
    public move(distanceInMeters: number) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}

private

class Animal {
    private name: string;
    constructor(theName: string) { this.name = theName; }
}

new Animal("Cat").name; // 错误: 'name' 是私有的.

protected

class Person {
    protected name: string;
    constructor(name: string) { this.name = name; }
}

class Employee extends Person {
    private department: string;

    constructor(name: string, department: string) {
        super(name)
        this.department = department;
    }

    public getElevatorPitch() {
        return `Hello, my name is ${this.name} and I work in ${this.department}.`;
    }
}

let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());
console.log(howard.name); // 错误

getter/setter

let passcode = "secret passcode";

class Employee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }

    set fullName(newName: string) {
        if (passcode && passcode == "secret passcode") {
            this._fullName = newName;
        }
        else {
            console.log("Error: Unauthorized update of employee!");
        }
    }
}

let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    alert(employee.fullName);
}

静态属性

class Grid {
    static origin = {x: 0, y: 0};
    calculateDistanceFromOrigin(point: {x: number; y: number;}) {
        let xDist = (point.x - Grid.origin.x);
        let yDist = (point.y - Grid.origin.y);
        return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
    }
    constructor (public scale: number) { }
}

let grid1 = new Grid(1.0);  // 1x scale
let grid2 = new Grid(5.0);  // 5x scale

console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

抽象类

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}

abstract class Department {

    constructor(public name: string) {
    }

    printName(): void {
        console.log('Department name: ' + this.name);
    }

    abstract printMeeting(): void; // 必须在派生类中实现
}

class AccountingDepartment extends Department {

    constructor() {
        super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
    }

    printMeeting(): void {
        console.log('The Accounting Department meets each Monday at 10am.');
    }

    generateReports(): void {
        console.log('Generating accounting reports...');
    }
}

let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在

函数

let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
    // Check to see if we're working with an object/array
    // if so, they gave us the deck and we'll pick the card
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // Otherwise just let them pick the card
    else if (typeof x == "number") {
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

泛型

function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}

泛型类

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

泛型约束

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}

类型参数

function getProperty(obj: T, key: K) {
    return obj[key];
}

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a"); // okay
getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.

泛型使用类类型

function create<T>(c: {new(): T; }): T {
    return new c();
}
class BeeKeeper {
    hasMask: boolean;
}

class ZooKeeper {
    nametag: string;
}

class Animal {
    numLegs: number;
}

class Bee extends Animal {
    keeper: BeeKeeper;
}

class Lion extends Animal {
    keeper: ZooKeeper;
}

function createInstance<A extends Animal>(c: new () => A): A {
    return new c();
}

createInstance(Lion).keeper.nametag;  // typechecks!
createInstance(Bee).keeper.hasMask;   // typechecks!

枚举

const enum Directions {
    Up,
    Down,
    Left,
    Right
}

let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]

外部枚举

declare enum Enum {
    A = 1,
    B,
    C = 2
}

Q.E.D.


别云剑本星 智多星本剑