TS系列之型別

zhouzhou發表於2019-02-16

基礎

安裝TS

npm install -g typescript

編譯

tsc hello.ts

型別

boolean、number、string、void、null、undefined、any、tuple、enum、never、symbol

boolean

let isDone: boolean = false;

number

let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
// ES6 中的二進位制表示法
let binaryLiteral: number = 0b1010;
// ES6 中的八進位制表示法
let octalLiteral: number = 0o744;
let notANumber: number = NaN;
let infinityNumber: number = Infinity;

string

let name: string = `Gene`;
let sentence: string = `Hello, my name is ${ name }.

Void

  • void型別表示沒有任何型別
  • 只能為它賦予undefined和null

null 和 undefined

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

any

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

  • 如果是一個普通型別,在賦值過程中改變型別是不被允許的,但如果是 any 型別,則允許被賦值為任意型別。
  • 宣告一個變數為任意值之後,對它的任何操作,返回的內容的型別都是任意值。
  • 變數如果在宣告的時候,未指定其型別,那麼它會被識別為任意值型別。
let something;          //let something: any;
something = `seven`;
something = 7;

tuple

元組表示一個已知元素數量和型別的陣列,各元素的型別不必相同。

let x: [string, number];
x = [`hello`, 10];        // OK
x = [10, `hello`];        // Error

enum

列舉成員預設會被賦值為從 0 開始遞增的數字,同時也會對列舉值到列舉名進行反向對映。

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};

console.log(Days["Sun"] === 0); // true
console.log(Days["Mon"] === 1); // true

console.log(Days[1] === "Mon"); // true
console.log(Days[2] === "Tue"); // true

數字列舉

enum Direction {
    Up,
    Down,
    Left,
    Right,
}
// Up的值為 0, Down的值為 1等等

enum Direction {
    Up = 1,
    Down,
    Left,
    Right
}
// Up使用初始化為 1,其餘的成員會從 1開始自動增長。

字串列舉

在一個字串列舉裡,每個成員都必須用字串字面量,或另外一個字串列舉成員進行初始化。

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}

never

never型別表示的是那些永不存在的值的型別。

function error(message: string): never {
    throw new Error(message);
}

never型別是任何型別的子型別,也可以賦值給任何型別;然而,沒有型別是never的子型別或可以賦值給never型別(除了never本身之外)。 即使 any也不可以賦值給never。

symbol

symbol型別的值是通過Symbol建構函式建立的。

let sym1 = Symbol();
let sym2 = Symbol("key"); 

let sym2 = Symbol("key");
let sym3 = Symbol("key");
sym2 === sym3; // false, symbols是唯一的

symbol是不可改變且唯一的。
symbol也可以被用做物件屬性的鍵

let sym = Symbol();
let obj = {
    [sym]: "value"
};
console.log(obj[sym]); // "value"

array、function

array

//型別[]
let fibonacci: number[] = [1, 1, 2, 3, 5];
//陣列泛型 Array<型別>
let fibonacci: Array<number> = [1, 1, 2, 3, 5];

function

一個函式有輸入和輸出,要在 TypeScript 中對其進行約束,需要把輸入和輸出都考慮到。

function add(x: number, y: number): number {
    return x + y;
}

輸入多餘的(或者少於要求的)引數,是不被允許的

//可選引數
function buildName(firstName: string, lastName = "Smith", fullName?: string) {
    return firstName + " " + lastName;
}

可選引數必須接在必需引數後面。換句話說,可選引數後面不允許再出現必須引數了。

函式表示式

let mySum = function (x: number, y: number): number {
    return x + y;
};

這是可以通過編譯的,不過事實上,上面的程式碼只對等號右側的匿名函式進行了型別定義,而等號左邊的 mySum,是通過賦值操作進行型別推論而推斷出來的。如果需要我們手動給 mySum 新增型別,則應該是這樣:

let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
};

注意不要混淆了 TypeScript 中的 => 和 ES6 中的 =>。
在 TypeScript 的型別定義中,=> 用來表示函式的定義,左邊是輸入型別,需要用括號括起來,右邊是輸出型別。

剩餘引數(…rest)

function push(array: any[], ...items: any[]) {
    items.forEach(function(item) {
        array.push(item);
    });
}

let a = [];
push(a, 1, 2, 3);

過載

過載允許一個函式接受不同數量或型別的引數時,作出不同的處理。

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
    if (typeof x === `number`) {
        return Number(x.toString().split(``).reverse().join(``));
    } else if (typeof x === `string`) {
        return x.split(``).reverse().join(``);
    }
}

TypeScript 會優先從最前面的函式定義開始匹配,所以多個函式定義如果有包含關係,需要優先把精確的定義寫在前面。

相關文章