TypeScript

介紹

TypeScript是JavaScript的超集,爲JavaScript的生態增長了類型機制,並最終將代碼編譯爲純粹的JavaScirpt代碼。javascript

編譯

瀏覽器加載文件編譯java

注意,編譯的TypeScript文件須要放在編譯文件以前typescript

<script src="lib/typescript.min.js" type="text/javascript" charset="utf-8"></script>
<script src="lib/typescript.compile.min.js" type="text/javascript" charset="utf-8"></script>

自動化構架工具gulp

1:fis數組

fis插件:fis-parser-typescript瀏覽器

var fis = require('fis3');

var typescirpt = require('fis3-parser-typescript');

fis.match('**.ts', {
    parser: fis.plugin('typescript'),
    rExt: '.js'
});

2: gulp
使用gulp插件:gulp-typescript安全

var gulp = require('gulp');

var ts = require('gulp-typescript');

gulp.task('compileTs', function () {
    
    gulp.src('**.ts')
        .pipe(ts())
        .pipe(gulp.dest('dist'));
    
});

gulp.task('default', ['compileTs']);

基礎類型

typescript囊括了全部JavaScript基本類型閉包

基本類型

  • number 數字類型app

  • string 字符串類型函數

  • boolean 布爾類型

  • any 任意一種

數組

定義數組
兩部分:前面一部分表示數組成員的類型,後面一部分表示告知是一個數組。

let arr:number[] = [12, 23];

let colors:any[] = [12, 'cyan', 'pink'];  // 數組任意類型

let list:Array<number> = [1, 2, 3]; // 數組泛型

元組

Tuple
元組類型容許表示一個已知元素數據和類型的數組,各元素的類型沒必要相同。

let x: [string, number] = ['cyan', 10];

訪問越界的元素,使用聯合類型替代。

枚舉

定義:enum colors { red, green, blue }
表義一種能夠一一列舉的數據

特色:

  • 經過索引值訪問定的數據。

  • 經過定義的數據訪問索引值。

  • 對枚舉類型的數據添加起始索引值。

enum color {
    red = 10, // 默認索引值從0 開始, 能夠指定索引值
    green,
    blue
}
// 編譯以後: Object {10: "red", 11: "green", 12: "blue", red: 10, green: 11, blue: 12}

空值

void 類型 像是 與 any 類型相反,它表示沒有任何類型。 當一個函數沒有返回值時, 要指定 void 類型。

void 類型 只能賦值: undefiend 和 null。

let unvoid: void = null;
let unvoid1: void = undefined;

undefiend和null

undefeind和null二者有各自的類型: undefined和null。 和void類似。

let u: undefined = undefined;
let n: null = null;

默認狀況下null 和undefined 是全部類型的子類型。
能夠把null 和undefined賦值給number類型的變量。

類型斷言

類型斷言,相似其它語言裏的類型轉換。可是不進行特殊的數據檢查和解構。 沒有運行時的影響,只是在編譯階段其做用。

尖括號<>語法

let someValue: any = 'colors'; 

let strlength: number = (<string>someValue).length;

console.log(strlength);

變量聲明

let&const

const 是對let的一個加強,能阻止對一個變量再次賦值。

let 和 const 的區別:
全部變量除了計劃要去修改的都應該使用const。
基本原則就是若是一個變量不須要對它寫入,那麼其它使用這些代碼的人也不可以寫入它們。
使用const能夠更容易推測數據的流動性。

解構

解構數組

不須要指定類型

let input = [1, 2];

let [fisrt, second] = input;

console.log(fisrt, second); // 1 ,2

對象結構

let o = {
    a: 'foo',
    b: 12,
    c: 'bar'
}

let {a, b} = o;

console.log( a, b );

函數

TypeScript函數能夠建立有名字的函數和匿名函數
TypeScript函數執行返回值須要定義數據類型,若是沒有結果則要定義爲void。
TypeScript函數,參數須要定義類型,在調用的時候,傳遞的參數必定要跟定義時的參數個數同樣。不然編譯報錯。

function add (a:number, b:number):number {
    return a + b;
}

let sum = add(10, 20);

console.log( sum );

// 定義void返回值

setProperty();

function setProperty (): void {
    
    console.log('success');
    
}

可選參數和默認參數

在TypeScript中能夠在參數名旁邊使用 ? 實現可選參數

function count (str1: string, str2?: string): string {
    
    return str1 + '--' + str2;
    
}

let reslut = count('xixi');

console.log( reslut );

剩餘參數

剩餘參數會被看成個數不限的可選參數。能夠一個都沒有,一樣也能夠有任意個。
語法:...nameProperty

function builName (numa1: string, ...restOfName: string[]) { // 剩餘參數保存在數組中
    
}

Class

在TypeScript中,能夠經過Class來定義一個類。在編譯以後,會編譯成JavaScript一個閉包函數類。

語法: class className {}

成員方法,成員屬性

在類中添加的屬性會編譯到構造函數中,該屬性若是不賦值,則不會被編譯.
在類中添加的方法會編譯到構造函數的Prototype上。

class Price {
    
    price: number = 10;
    
    fn( num: number ): string {
        return num * 2;
    }
    
}

編譯以後的結果:

//Compiled TypeScript
var Price = (function () {
    function Price() {
        this.price = 10;
    }
    Price.prototype.fn = function (num) {
        return num * 2;
    };
    return Price;
})();

靜態屬性,靜態方法

靜態屬性:經過static關鍵字定義,定義的該屬性,在 類中訪問不到, 由於定義在類上。
靜態方法:經過static關鍵字定義,定義的該方法,在類中是訪問不到(不能經過this訪問),由於該方法定義在類上。

class Person {
    
    static name: string = 'time';
    
    static fn(num: number): void {
        
        console.log('success');
        
    }
    
}
let p1: Peson  = new Person(); // 實例化

編譯以後:

var Person = (function () {
    function Person() {
    }
    Person.fn = function (num) {
        console.log('success');
        console.log(Peson.name);
    };
    Person.name = 'time';
    return Person;
})();
var p1 = new Person();

構造函數

在實例化的時候被調用
構造函數中定義的語句會編譯到JavaScript的構造函數中。
構造函數不能聲明返回類型。
類定義的屬性(賦值的屬性)會被編譯到JavaScirpt的構造函數中。

class Book {
    
    name: string;
    
    page: number = 400;
    
    constructor(bookName: string) {
        
        this.name = bookName;
        
        console.log(bookName);
        
    }
    
}

let p1: Book = new Book('莊子');

編譯以後:

var Book = (function () {
    function Book(bookName) {
        this.page = 400;
        this.name = bookName;
        console.log(bookName);
    }
    return Book;
})();
var p1 = new Book('莊子');

繼承

語法:子類 extends 父類

class Base {
    
    press: string = 'one';    
        
}

class Book extends Base {
    
    name: string = '老子';
    
    sayName(): string {
        return this.name;
    }
    
}

let b: Book = new Book();

let bookname = b.sayName();

console.log(bookname);

編譯以後:
經過的是混合式繼承

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var Base = (function () {
    function Base() {
        this.press = 'one';
    }
    return Base;
})();
var Book = (function (_super) {
    __extends(Book, _super);
    function Book() {
        _super.apply(this, arguments);
        this.name = '老子';
    }
    Book.prototype.sayName = function () {
        return this.name;
    };
    return Book;
})(Base);
var b = new Book();
var bookname = b.sayName();
console.log(bookname);

——extends(); 方法

var __extends = this.__extends || function (d, b) { // b 父類
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};

目的, 實現只繼承 父類的原型對象。 從原型對象入手
1,function __() {}建立一個空函數, 目的:空函數進行中轉,把父類的模板屏蔽掉, 父類的原型取到。
2,__.prototype = b.prototype實現空函數的原型對象 和 超類的原型對象轉換
3,d.prototype = new __()原型繼承

使用for-in循環,子類繼承父類的靜態屬性或方法。(經過一個函數中轉,實現,只實例化一次,且繼承了一次父類的原型對象)
經過寄生類繼承父類原型上的屬性或方法。
在子類中運行構造函數式繼承實現對父類的構造函數繼承。

super()
在包含constructor函數的子類中必須調用super().它會執行基類的構造方法。

傳遞給super()方法就是實現構造函數繼承屬性
子類構造函數中添加屬性。
繼承父類構造函數中的屬性,若是子類定義構造函數就必須繼承。

class Base {
    
    press: string = 'one';
    name: string;
    constructor ( bookName: string ) {
        this.name = bookName;
    }
        
}

class Book extends Base {
    
    price: number;
//    name: string = '老子';
    
    constructor(bookName: string, price: number) {
        // 父類繼承屬性
        super(bookName); // 會執行父類的 constructor
        
        this.price = price;
        
    }
    
    sayName(): string {
        return this.name;
    }
    
}

let b: Book = new Book('老子', 40);

let bookname = b.sayName();

console.log(bookname);

接口

在TypeScript中,接口的做用:爲這些類型命名和爲你的代碼或第三方代碼定義契約。
TypeScript的核心原則之一是:對值所具備的shape進行類型檢查。
定義一種數據格式,來約束變量的類型。
接口中定義的每一個接口,均可以看成一種類型來使用。
可選實現成員,能夠在後面添加?.

語法:interface names {};

接口定義對象

// 定義接口
interface Person {
    name: string;
    age: number;
    sex: string;
    hobby?: any;
}

// 使用接口
function getName (person: Person): string {
    
    return person.name;
    
}

// 實現接口
var n: string = getName({
    name: 'one',
    age: 23,
    sex: 'nv'
});

console.log(n);

接口函數

語法:interface name {}
定義函數格式.經過()來定義參數個數,並聲明函數返回值類型。

做用:限制了定義該函數類型的規範。

// 定義抽象類
interface Add {
    (num1: number, num2: number): number;
}

// 使用接口 
let fn:Add;

// 實現接口
fn = function ( num1: number, num2: number ): number {
    
    return num1 + num2;
    
}

var  reslut: number = fn(10 , 20);

console.log(reslut);

類的接口定義

語法:

interface className {
    key: type;
    fn(arg: type): type;    
}

實現接口:

class Times implements Base {}

做用:保證代碼的安全性

'use strict';

// 時間接口
interface Base {
    current: string;
    getCurrentDate(): string;
}


// 使用接口
class Times implements Base {
    
    current: string;
    
    constructor( d: string ){
        this.current = d;
    }
    
    getCurrentDate (): string {
        return this.current;
    }
    
}

let d: Times = new Times(new Date().toString());

console.log(d);

模塊

在TypeScript1.5中:內部模塊 是說所的命名空間外部模塊則稱之爲模塊

語法:

module name {}

經過 export關鍵字, 將模塊的方法屬性暴露出來。
在模塊的外部訪問模塊,須要經過模塊名稱,點語法調用模塊內部暴露的接口

'use strict';

// 定義模塊

module startModuel {
    
    let info: string = 'colors';
    
    // 暴露一個class
    export class Satrt {
        
        name: string;
        
        constructor(name: string) {
            
            this.name = name;
            
        }
        
        getName(): string {
            
            return this.name;
            
        }
        
    }
    
}


// 實例化模塊中暴露的接口
let satr:startModuel.Satrt = new startModuel.Satrt('cyan');

console.log( satr );

console.log(satr.getName());

模塊在其自身的做用域裏執行,而不是在全局做用域裏。
一個模塊裏的比那兩,函數,類等等在模塊外部是不可見的,須要經過export形式向外暴露。
若是一個模塊想使用其它模塊導出的變量,函數,類,接口等。須要使用import造成引入。

模塊是自聲明的。兩個模塊之間的關係是經過在文件級別上使用imports和 exports 創建聯繫的。

導出

導出聲明

export interface StringValidator {
    
    isAcce(s: string): boolean;
    
}

export const numberRegExp = /^[0-9]+$/;

導出語句

export class ZipCode implements  StringValidator {
    
    isAcce(s: string) {
        return s.length === 5 && numberRegExp.test(s);
    }
    
}

// 導出語句
export { ZipCode }

導入

使用關鍵字:import 來導入其它模塊中的導出內容

import { ZipCode } form './ZipCode';

let myValid = new ZipCode();

// 對導入的內容從新命名
import {ZipCode as ZVC } form ''./ZipCode;

let  myValid = new ZVC();

默認導出

每一個模快都有一個defalut導出。 默認導出使用default 關鍵字標記。
例如:JQuery的類庫有一個默認導出JQuery或$.

let $:jQuery;     
export default $;

import $ from 'JQuery';

模塊路徑解析

TypeScript存在兩種路徑解析方式: Node和Classic(本來TypeScirpt路徑解析規則,爲了向後兼容)

TypeScript是模範Node運行時解析策略來編譯階段定義模塊文件。
TypeScript在Node解析邏輯基礎上增長了TypeScript源文件的擴展名(.ts,.tsx,.d.ts).

命名空間

命名空間是位於全局命名空間下的一個普通的帶有名字的JavaScript對象

使用關鍵字:namespace

namescope Valiation {
    export interface StringValidator {
        isAcce(s: string): boolean;
    }
    
    const lettesRegExp = /^[A-Za-z]+$/;
    
}

多文件的命名空間

不一樣的文件,可是還是同一個命名空間,而且在使用的時候,就如同他們在一個文件中定義的同樣。 由於不一樣文件之間存在依賴關係,因此加入了引用標籤來告知編譯器文件之間的關聯。

namescope Valiation {
    export interface StringValidator {
        isAcce(s: string): boolean;
    }
}

namescope Valiation {
    const lettesRegExp = /^[A-Za-z]+$/;
    expots class LetterOnly implements StringValidator {
        isAcce(s: string): boolean {
            return s.length && lettesRegExp.test(s);
        }
    }
}

// 測試
/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />

let strings = ["Hello", "98052"];

let validators: { [s: string]: Validation.StringValidator; } = {};

validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();

strings.forEach(s => {
    for (let name in validators) {
        console.log(""" + s + "" " + (validators[name].isAcce(s) ? " matches " : " does not match ") + name);
    }
});

編譯方式:

  • 把全部輸入的文件編譯一個輸出文件,須要使用--outFile標記

    tsc --outFile sample.js Test.ts
    變異其會根據源碼中引用標籤自動的對輸出進行排序。
    能夠單獨指定每一個文件
    tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts

  • 能夠編譯成每個文件(默認方式),每一個源文件都會對應生成一個JavaScript文件。而後,在頁面上經過<script>標籤吧全部生成的JavaScript文件按正確的順序引進來。

相關文章
相關標籤/搜索