前言
由於自己目前在學習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基礎的一個學習。也是自己學習的一個筆記。奈何水平有限,望各位大佬指出問題,謝謝!