初探TypeScript 基礎篇

前端平民發表於2019-04-18

前言

由於自己目前在學習typescript;想著邊學習變做筆記,往後也可以翻出來看看,也分享出來給像我一樣的初學者一起學習。望各位大佬指教。

簡介

什麼是TypeScript

TypeScript是Javascript的型別的超級,它可以編輯成Javascript,編譯出來的程式碼可以執行在任何瀏覽器上,TypeScript編譯工具可以執行在任何伺服器和系統上,並且它是開源的。
複製程式碼

為什麼要選擇TypeScript

1. TypeScript增加了程式碼的可讀性和可維護性
    可以在編輯的夾斷就發現大部分錯誤,比在執行程式的時候發現錯誤更加直觀;
    增強了編輯器和IDE的功能,包括程式碼補全、介面提示等等
2. 擁有活躍的社群
    大部分第三方庫都有提供TypeScript的型別定義檔案
複製程式碼

安裝TypeScript

TypeScript 的命令列工具安裝方法如下:

npm i -g typescript

以上命令會在全域性環境下安裝 tsc 命令,安裝以後我們就可以在任何終端執行tsc命令了。我們可以簡單的建立一個檔案 hello.tsc 我們可以通過命令到當前檔案所在目錄,執行命令

tsc hello.tsc

編輯前程式碼 hello.tsc

function sayHello(person: string) {
    return `Hello,${person}`;
}
let user = 'Mark';
console.log(sayHello(user));
複製程式碼

執行tsc hello.tsc後我們會看到同級目錄下面會自動生成一個hello.js

function sayHello(person) {
    return `Hello,${person}`;
}
let user = 'Mark';
console.log(sayHello(user));
複製程式碼

加入我們在sayHello方法中傳入的是一個非string型別的引數 會發生什麼呢

function sayHello(person: string) {
    return `Hello,${person}`;
}
let user = 10010;
console.log(sayHello(user));
複製程式碼

編輯器中會提示錯誤,編譯的時候也會出錯:Argument of type 'number' is not assignable to parameter of type 'string'. 此時你會發現 TypeScript 編譯的時候即使報錯了,還是會生成編譯結果,我們仍然可以使用這個編譯之後的檔案。

基礎

上面簡單的介紹了下TypeScript的安裝及簡單的hello例項,下面會介紹TypeScript 中的常用型別和一些基本概念,這樣可以對TypeScript有個初步的瞭解;

原始資料型別

原始資料型別只要包括:boolean number string null undefined 以及es6中新的型別Symbol; 下面我們介紹:boolean number string null undefined在TypeScript中的使用

boolean

boolean是最基礎的資料型別,在TypeScript 使用boolean定義布林值型別;

    let isSay: boolean = false; //編譯通過
    // 我們在看下面一個 假如我們使用建構函式建立一個布林值是否會編譯用過呢????
    let createBoolean: boolean = new Boolean(8); // Type 'Boolean' is not assignable to type 'boolean'.
    // 所以使用建構函式 Boolean 創造的物件不是布林值:
複製程式碼

number

使用number定義數值型別:

    let age: number = 25 // 編譯通過
    // 同樣如果我們age變數賦值的為非number 編譯就會報錯
複製程式碼

string

使用string定義數值型別:

    let name: string = 'mark' // 編譯通過
    // 同樣如果我們name變數賦值的為非string 編譯就會報錯
複製程式碼

空值

在JavaScript中是沒有空值(Void)的概念,但是在 TypeScript 中,可以用 void 表示沒有任何返回值的函式:

    function sayHello(): void{
        console.log('我沒有任何返回值');
    }
複製程式碼

null & undefined

在 TypeScript 中,可以使用 null 和 undefined 來定義這兩個原始資料型別:

    let m: undefined = undefined;
    let n: null = null;
複製程式碼

注意: 因為undefined 和 null 是所有型別的子型別,所以null undefined可以賦值給其他型別

    let m: undefined = undefined;
    let age: number = m;
    // 編輯通過
複製程式碼

任意值

任意值(any)用來表示允許賦值為任意型別。

什麼是任意值型別

上面我們說到,如果是一個普通型別,在賦值的過程中改變型別是不允許的 但是如果是any型別,那麼允許被賦值為任意型別。

    let age: number = 1; // 普通型別只能賦值number
    age = 'one'; // 報錯
    let anyAge: any = 'one'; 
    anyAge = 1; // 編輯通過
複製程式碼

型別推論

如果沒有明確的指定型別,那麼 TypeScript 會依照型別推論的規則推斷出一個型別。 例如:

    let age = 1;
    age = 'one';
    //TypeScript 會在沒有明確的指定型別的時候推測出一個型別 
    等價於
    let age: number = 1;
    age = 'one';
複製程式碼

聯合型別

聯合型別?

聯合型別表示取值可以為多種型別中的一種。

    let age: string | number;
    age = 1;
    age = 'one';
    // 以上編譯是通過的;
    // 如果age是boolean呢
    age = false; // 編譯報錯
複製程式碼

通過以上程式碼 可以得到一個結論:let age: string | number時,age的型別只能是string or number ,不能是其他型別。

訪問聯合型別的屬性和方法

當 TypeScript 不確定一個聯合型別的變數到底是哪個型別的時候,我們只能訪問此聯合型別的所有型別裡共有的屬性或方法:

    let age: string | number;
    age = 1;
    console.log( age.length ); // 編譯時報錯
    age = 'one';
    console.log( age.length ); // 3
複製程式碼

物件的型別

物件的型別在 TypeScript 中我們使用介面來定義-- interfaces

interface Person {
    name: string;
    age: number;
}
let user: Person = {
    name: 'mark',
    age: 1,
}
// 假如我們
let user1: Person = {
    name: 'mark',
}
// or
let user2: Person = {
    name: 'mark',
    age: 1,
    work: 'web',
}
// 編輯報錯
複製程式碼

定義得變數比介面少了一些屬性和多了一些屬性都是不允許的,編譯都會報錯,所以在賦值的時候,變數的形狀必須和介面保持一致。

假如我們想不要完全匹配一個形狀 可以隨意新增和減少怎麼辦呢?這個時候可以用到可選屬性和任意屬性 可選屬性:該屬性可以不存在 任意屬性: 該屬性可以是任意型別,但是要注意: 一旦定義了任意屬性,那麼確定屬性和可選屬性的型別必須是它的型別的子集。

insterface Person {
    name: string;
    age?: number;
    [propName: string]: any;
}
let user: Person = {
    name: 'mark',
    age: 1,
    work: 'web'
};
// 如果任意型別定義為string 那麼 上面程式碼會報錯。
insterface Person {
    name: string;
    age?: number;
    [propName: string]: string; //error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'
}

複製程式碼

我們在平常工作中經常會希望有些欄位只能在建立的時候被賦值,比如資料中的id; 在TypeScript中如何定義只讀屬性呢?

interface Person {
    readonly id: number;
    name: string;
    age?: number;
    [propName: string]: any;
}

let user: Person = {
    id: 1,
    name: 'mar;',
    work: 'web'
};
user.id = 2;
// 報錯 Cannot assign to 'id' because it is a constant or a read-only property.
複製程式碼

陣列的型別

陣列型別的表示方法:

型別+[] 表示法

let ages: number[] = [1,2,3,4,5];
let ages1: number[] = [1, 2, 3, '4']; // 報錯
ages.push('2'); // 報錯
複製程式碼

陣列泛型 Array<型別>

let ages: Array<number> = [1, 2, 3];
複製程式碼

用介面表示陣列

interface NumberArray {
    [index: number]: number;
}
let ages: NumberArray = [1, 1, 2, 3, 5];
複製程式碼

函式的型別

一個函式有輸入和輸出,要在 TypeScript 中對其進行約束,需要把輸入和輸出都考慮到,其中函式宣告的型別定義較簡單:

function sum(x: number, y: number): number {
    return x + y;
}
// es6 => 用來表示函式的定義,左邊是輸入型別,需要用括號括起來,右邊是輸出型別
let sum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
};

複製程式碼

同樣 跟其他型別一樣 輸入多餘的(或者少於要求的)引數,是不被允許的:

總結

以上是對TypeScript基礎的一個學習。也是自己學習的一個筆記。奈何水平有限,望各位大佬指出問題,謝謝!

相關文章