從 JavaScript 到 TypeScript

來源:互聯網
上載者:User

標籤:基礎上   java   test   很多   script   readonly   引用   相同   運行   

從 JavaScript 到 TypeScript

TypeScript 並不是一個完全新的語言, 它是 JavaScript 的超集,為 JavaScript 的生態增加了類型機制,並最終將代碼編譯為純粹的 JavaScript 代碼。

TypeScript 簡介

TypeScript 由 Microsoft(算上 Angular 2 的話加上 Google)開發和維護的一種開源程式設計語言。 它支援 JavaScript 的所有文法和語義,同時通過作為 ECMAScript 的超集來提供一些額外的功能,如類型檢測和更豐富的文法。顯示了 TypeScript 與 ES5,ES2015,ES2016 之間的關係。

使用 TypeScript 的原因

JavaScript 是一門弱類型語言,變數的資料類型具有動態性,只有執行時才能確定變數的類型,這種後知後覺的認錯方法會讓開發人員成為調試大師,但無益於編程能力的提升,還會降低開發效率。TypeScript 的類型機制可以有效杜絕由變數類型引起的誤用問題,而且開發人員可以控制對類型的監控程度,是嚴格限制變數類型還是寬鬆限制變數類型,都取決於開發人員的開發需求。添加類型機制之後,副作用主要有兩個:增大了開發人員的學習曲線,增加了設定類型的開發時間。總體而言,這些付出相對於代碼的健壯性和可維護性,都是值得的。

此外,類型注釋是 TypeScript 的內建功能之一,允許文字編輯器和 IDE 可以對我們的代碼執行更好的靜態分析。 這意味著我們可以通過自動編譯工具的協助,在編寫代碼時減少錯誤,從而提高我們的生產力。

對 TypeScript 的簡介到此,接下來對其特有的知識點進行簡單概括總結,(網上很多教程實際上把 ES6, ES7 的知識點也算進 ts 的知識點了,當然這沒錯~)

資料類型String 類型

一個儲存字串的文本,型別宣告為 string。可以發現型別宣告可大寫也可小寫,後文同理。

let name: string = 'muyy'let name2: String = 'muyy'
Boolen 類型

boolean是 true 或 false 的值,所以 let isBool3: boolean = new Boolean(1) 就會編譯報錯,因為 new Boolean(1) 產生的是一個 Bool 對象。

let isBool1: boolean = false
Number 類型
let number: number = 10;
Array 類型

數組是 Array 類型。然而,因為數組是一個集合,我們還需要指定在數組中的元素的類型。我們通過 Array<type> or type[] 文法為數組內的元素指定類型

let arr:number[] = [1, 2, 3, 4, 5];let arr2:Array&lt;number&gt; = [1, 2, 3, 4, 5];let arr3:string[] = ["1","2"];let arr4:Array&lt;string&gt; = ["1","2"];
Enums 類型

列出所有可用值,一個枚舉的預設初始值是0。你可以調整一開始的範圍:

enum Role {Employee = 3, Manager, Admin}let role: Role = Role.Employeeconsole.log(role) // 3
Any 類型

any 是預設的類型,其類型的變數允許任何類型的值:

let notSure:any = 10;let notSure2:any[] = [1,"2",false];
Void 類型

JavaScript 沒有空值 Void 的概念,在 TypeScirpt 中,可以用 void 表示沒有任何傳回值的函數:

function alertName(): void {  console.log('My name is muyy')}
函數為函數定義類型

我們可以給每個參數添加類型之後再為函數本身添加傳回值類型。 TypeScript能夠根據返回語句自動推斷出傳回值類型,因此我們通常省略它。下面函數 add, add2, add3 的效果是一樣的,其中是 add3 函數是函數完整類型。

function add(x: string, y: string): string{    return "Hello TypeScript";}let add2 = function(x: string, y: string): string{    return "Hello TypeScript";}let add3: (x: string, y: string) => string = function(x: string, y: string): string{    return "Hello TypeScript";}
選擇性參數和預設參數

JavaScript 裡,每個參數都是可選的,可傳可不傳。 沒傳參的時候,它的值就是 undefined 。 在 TypeScript 裡我們可以在參數名旁使用?實現選擇性參數的功能。 比如,我們想讓 lastname 是可選的:

function buildName(firstName: string, lastname?: string){    console.log(lastname ? firstName + "" + lastname : firstName)}let res1 = buildName("鳴","人"); // 鳴人let res2 = buildName("鳴"); // 鳴let res3 = buildName("鳴", "人", "君"); // Supplied parameters do not match any signature of call target.

如果帶預設值的參數出現在必須參數前面,使用者必須明確的傳入 undefined 值來獲得預設值。 例如,我們重寫上例子,讓 firstName 是帶預設值的參數:

function buildName2(firstName = "鳴", lastName?: string){    console.log(firstName + "" + lastName)}let res4 = buildName2("人"); // undefined人let res5 = buildName2(undefined, "人"); // 鳴人

傳統的JavaScript程式使用函數和基於原型的繼承來建立可重用的組件,但對於熟悉使用物件導向方式的程式員來講就有些棘手,因為他們用的是基於類的繼承並且對象是由類構建出來的。 從ECMAScript 2015,也就是ECMAScript 6開始,JavaScript程式員將能夠使用基於類的物件導向的方式。 使用TypeScript,我們允許開發人員現在就使用這些特性,並且編譯後的JavaScript可以在所有主流瀏覽器和平台上運行,而不需要等到下個JavaScript版本。

class Person{    name:string; // 這個是對後文this.name類型的定義    age:number;    constructor(name:string,age:number){        this.name = name;        this.age = age;    }    print(){        return this.name + this.age;    }}let person:Person = new Person('muyy',23)console.log(person.print()) // muyy23

我們在引用任何一個類成員的時候都用了 this。 它表示我們訪問的是類的成員。其實這本質上還是 ES6 的知識,只是在 ES6 的基礎上多上了對 this 欄位和引用參數的型別宣告。

繼承
class Person{    public name:string;  // public、private、static 是 typescript 中的類存取修飾詞    age:number;    constructor(name:string,age:number){        this.name = name;        this.age = age;    }    tell(){        console.log(this.name + this.age);    }}class Student extends Person{    gender:string;    constructor(gender:string){        super("muyy",23);        this.gender = gender;    }    tell(){        console.log(this.name + this.age + this.gender);    }}var student = new Student("male");student.tell();  // muyy23male

這個例子展示了 TypeScript 中繼承的一些特徵,可以看到其實也是 ES6 的知識上加上型別宣告。不過這裡多了一個知識點 —— 公用,私人,以及受保護的修飾符。TypeScript 裡,成員預設為 public ;當成員被標記成 private 時,它就不能在聲明它的類的外部存取;protected 修飾符與private 修飾符的行為很相似,但有一點不同,protected 成員在衍生類別中仍然可以訪問。

儲存空間

TypeScript 支援通過 getters/setters 來截取對對象成員的訪問。 它能協助你有效控制對對象成員的訪問。

對於存取器有下面幾點需要注意的:
首先,存取器要求你將編譯器設定為輸出 ECMAScript 5 或更高。 不支援降級到 ECMAScript 3。 其次,只帶有 get 不帶有 set 的存取器自動被推斷為 readonly。 這在從代碼產生 .d.ts 檔案時是有協助的,因為利用這個屬性的使用者會看到不允許夠改變它的值。

class Hello{    private _name: string;    private _age: number;    get name(): string {        return this._name;    }    set name(value: string) {        this._name = value;    }    get age(): number{        return this._age;    }    set age(age: number) {        if(age&gt;0 && age&lt;100){            console.log("年齡在0-100之間"); // 年齡在0-100之間            return;        }        this._age = age;    }}let hello = new Hello();hello.name = "muyy";hello.age = 23console.log(hello.name); // muyy
介面介面

TypeScript的核心原則之一是對值所具有的結構進行類型檢查。在TypeScript裡,介面的作用就是為這些類型命名和為你的代碼或第三方代碼定義契約。

interface LabelValue{    label: string;}function printLabel(labelObj: LabelValue){    console.log(labelObj.label);}let myObj = {    "label":"hello Interface"};printLabel(myObj);

LabelledValue 介面就好比一個名字,它代表了有一個 label 屬性且類型為 string 的對象。只要傳入的對象滿足上述必要條件,那麼它就是被允許的。

另外,類型檢查器不會去檢查屬性的順序,只要相應的屬性存在並且類型也是對的就可以。

可選屬性

帶有可選屬性的介面與普通的介面定義差不多,只是在可選屬性名稱字定義的後面加一個 ? 符號。可選屬性的好處之一是可以對可能存在的屬性進行預定義,好處之二是可以捕獲引用了不存在的屬性時的錯誤。

interface Person{    name?:string;    age?:number;}function printInfo(info:Person){    console.log(info);}let info = {    "name":"muyy",    "age":23};printInfo(info); // {"name": "muyy", "age": 23}let info2 = {    "name":"muyy"};printInfo(info2); // {"name": "muyy"}
函數類型

介面能夠描述 JavaScript 中對象擁有的各種各樣的外形。 除了描述帶有屬性的普通對象外,介面也可以描述函數類型。定義的函數類型介面就像是一個只有參數列表和傳回值類型的函數定義。參數列表裡的每個參數都需要名字和類型。定義後完成後,我們可以像使用其它介面一樣使用這個函數類型的介面。

interface SearchFunc{    (source: string, subString: string): boolean;}let mySearch: SearchFunc;mySearch = function(source: string,subString: string){    return source.search(subString) !== -1;};console.log(mySearch("鳴人","鳴")); // trueconsole.log(mySearch("鳴人","纓")); // false
可索引類型

與使用介面描述函數類型差不多,我們也可以描述那些能夠“通過索引得到”的類型,比如 a[10] 或 ageMap["daniel"]。 可索引類型具有一個索引簽章,它描述了對象索引的類型,還有相應的索引傳回值類型。 讓我們看如下例子:

interface StringArray{    [index: number]: string;}let MyArray: StringArray;MyArray = ["是","雲","隨","風"];console.log(MyArray[2]); // 隨
類類型

與 C# 或 Java 裡介面的基本作用一樣,TypeScript 也能夠用它來明確的強制一個類去符合某種契約。

我們可以在介面中描述一個方法,在類裡實現它,如同下面的 setTime 方法一樣:

interface ClockInterface{    currentTime: Date;    setTime(d: Date);}class Clock implements ClockInterface{    currentTime: Date;    setTime(d: Date){        this.currentTime = d;    }    constructor(h: number, m: number) {}}
繼承介面

和類一樣,介面也可以相互繼承。 這讓我們能夠從一個介面裡複製成員到另一個介面裡,可以更靈活地將介面分割到可重用的模組裡。

interface Shape{    color: string;}interface PenStroke{    penWidth: number;}interface Square extends Shape,PenStroke{    sideLength: number;}let s = &lt;Square&gt;{};s.color = "blue";s.penWidth = 100;s.sideLength = 10;
模組

TypeScript 與 ECMAScript 2015 一樣,任何包含頂級 import 或者 export 的檔案都被當成一個模組。

export interface StringValidator{    isAcceptable(s:string): boolean;}var strReg = /^[A-Za-z]+$/;var numReg = /^[0-9]+$/;export class letterValidator implements StringValidator{    isAcceptable(s:string): boolean{        return strReg.test(s);    }}export class zipCode implements StringValidator{    isAcceptable(s: string): boolean{        return s.length == 5 && numReg.test(s);    }}
泛型

軟體工程中,我們不僅要建立一致的定義良好的 API ,同時也要考慮可重用性。 組件不僅能夠支援當前的資料類型,同時也能支援未來的資料類型,這在建立大型系統時為你提供了十分靈活的功能。
在像 C# 和 Java 這樣的語言中,可以使用泛型來建立可重用的組件,一個組件可以支援多種類型的資料。 這樣使用者就可以以自己的資料類型來使用組件。

初探泛型

如下代碼,我們給 Hello 函數添加了類型變數 T ,T 協助我們捕獲使用者傳入的類型(比如:string)。我們把這個版本的 Hello 函數叫做泛型,因為它可以適用於多個類型。 代碼中 output 和 output2 是效果是相同的,第二種方法更加普遍,利用了類型推論 —— 即編譯器會根據傳入的參數自動地協助我們確定T的類型:

function Hello&lt;T&gt;(arg:T):T{    return arg;}let outPut = Hello&lt;string&gt;('Hello Generic');let output2 = Hello('Hello Generic')console.log(outPut);console.log(outPut2);
參考資料
  • TypeScript 中文文檔
  • TypeScript
  • TypeScript for Angular 2 - Part 1 (An Introduction)

原文地址:http://muyunyun.cn/posts/66a54fc2/

從 JavaScript 到 TypeScript

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.