TypeScript 基本類型和泛型的使用

寫在前面的話:

  • 迫於業務升級,開始使用 typescript,這裏來了解一下 typescript 的基本類型和泛型的使用。如今 typescript 已經 3.1版本了,很是成熟了。

typeScript 基礎類型

  • 下面只介紹一些區別於 JavaScript 的特殊類型

Tuple 元組

  • 元組類型容許表示一個已知元素數量和類型的數組,各元素的類型沒必要相同。好比,你能夠定義一對值分別爲 string 和 number 類型的元組。
// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error
複製代碼

enum 枚舉

  • enum 類型是對 JavaScript 標準數據類型的一個補充。像 C#等其餘語言同樣,使用枚舉類型能夠爲一組數值賦予友好的名字。
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
複製代碼
  • 默認狀況下,從0開始爲元素編號。 你也能夠手動的指定成員的數值。 例如,咱們將上面的例子改爲從 1開始編號:
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
複製代碼

Any

  • 有時候,咱們會想要爲那些在編程階段還不清楚類型的變量指定一個類型。 這些值可能來自於動態的內容,好比來自用戶輸入或第三方代碼庫。 這種狀況下,咱們不但願類型檢查器對這些值進行檢查而是直接讓它們經過編譯階段的檢查。 那麼咱們可使用 any類型來標記這些變量:
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
複製代碼
let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)

let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

複製代碼

Void

  • 這玩意通常用在 func 上,剛剛和 Any 相反
function warnUser(): void {
    console.log("This is my warning message");
}

//聲明一個void類型的變量沒有什麼大用,由於你只能爲它賦予undefined和null:
let unusable: void = undefined
複製代碼

Null 和 Undefined

  • TypeScript裏,undefined和null二者各自有本身的類型分別叫作undefined和null。 和 void類似,它們的自己的類型用處不是很大:
// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;
複製代碼

Never

  • never類型表示的是那些永不存在的值的類型。 例如, never類型是那些老是會拋出異常或根本就不會有返回值的函數表達式或箭頭函數表達式的返回值類型; 變量也多是 never類型,當它們被永不爲真的類型保護所約束時。
// 返回never的函數必須存在沒法達到的終點
function error(message: string): never {
    throw new Error(message);
}

// 推斷的返回值類型爲never
function fail() {
    return error("Something failed");
}

// 返回never的函數必須存在沒法達到的終點
function infiniteLoop(): never {
    while (true) {
    }
}
複製代碼

typescript 泛型

先來談談使用場景

  • 模擬一個場景,當咱們要使用一個服務器提供的不一樣數據,咱們須要先創建一箇中間件來進行處理(驗證,容錯,糾正),再進行使用。使用 JavaScript 來寫 。

JavaScript

// 模擬服務,提供不一樣的數據。這裏模擬了一個字符串和一個數值
var service = {
    getStringValue: function() {
        return "a string value";
    },
    getNumberValue: function() {
        return 20;
    }
};

// 處理數據的中間件。這裏用 log 來模擬處理,直接返回數據看成處理後的數據
function middleware(value) {
    console.log(value);
    return value;
}

// JS 中對於類型並不關心,因此這裏沒什麼問題
var sValue = middleware(service.getStringValue());
var nValue = middleware(service.getNumberValue());
複製代碼

typeScript

  • 服務器返回的類型要進行必定的限制
const service = {
    getStringValue(): string {
        return "a string value";
    },

    getNumberValue(): number {
        return 20;
    }
};
複製代碼
  • 爲了保證在對 sValue 和 nValue 的後續操做中類型檢查有效,它們也會有類型(若是 middleware 類型定義得當,能夠推導,這裏咱們先顯示定義其類型)
const sValue: string = middleware(service.getStringValue());
const nValue: number = middleware(service.getNumberValue());
複製代碼

換成 typescript 的時候咱們的中間件 middleware ,須要返回正確的 stringnumber類型。咱們須要怎麼作啦?javascript

方法一,特殊類型 any

function middleware(value: any): any{
    console.log(value);
    return value;
}

複製代碼

這個方法可讓最後的類型檢測經過,可是使用 any 的話,導致 middleware 就沒有什麼用了。html

方法二,多個middleware

function middleware1(value: string): string { ... }
function middleware2(value: number): number { ... }
複製代碼
  • 使用 typescript 的重載(overload)
function middleware(value: string): string; function middleware(value: number): number; function middleware(value: any): any {
    // 實現同樣沒有嚴格的類型檢查
}
複製代碼

可是類型過多的話這種方法也很差使。java

正解: 使用 typescript 泛型(Generic)

  • 先簡單的來講一下什麼是泛型?
  • 就是表示一個類型的變量,用他來代替某個實際的類型用於編程。
function middleware<T>(value: T): T {
    console.log(value);
    return value;
}
複製代碼

middleware 後面緊接的 <T> 表示聲明一個表示類型的變量,Value: T 表示聲明參數是 T 類型的,後面的 : T 表示返回值也是 T 類型的。那麼在調用 middlewre(getStringValue()) 的時候,因爲參數推導出來是 string 類型,因此這個時候 T 表明了 string,所以此時 middleware 的返回類型也就是 string;而對於middleware(getNumberValue()) 調用來講,這裏的 T 表示了 numbertypescript

  • 若是你使用 vscode 的話,咱們默認你已經安裝的支持 typescript 的環境。能夠看到咱們在推導類型和返回值類型的時候,vscode 會提示你對應的 stringnumber的類型。

參考

相關文章
相關標籤/搜索