TypeScript 學習總結 基礎數據類型(一)

寫在前面javascript

由於typescript文檔我的感受寫得很差(概念過於雜亂,示例代碼有錯誤~)。因此總結一下TS的知識java

這是我的學習筆記總結,並無官方文檔嚴謹。更多的是我的的大白話react

代碼部分 推薦各位複製到支持TS的代碼編輯器裏 看看什麼效果。體驗一下 TS在編譯階段的嚴謹~~typescript

想學習TypeScript的朋友能夠快速掃兩眼,入個門~ json


基礎數據類型:


首先typescript的基礎數據類型:redux

  • 布爾類型(boolean)數組

  • 數字類型(number)dom

  • 字符串類型(string)編輯器

  • 數組類型(array)函數

  • 元組類型(tuple)

  • 枚舉類型(enum)

  • 任意值類型(any)

  • null 和 undefined

  • void類型

  • never類型

  • object 類型

  • 類型斷言

  • Symbol 類型


布爾類型(boolean)


布爾類型是最簡單的數據類型,只能賦值爲truefalse兩種值,不能賦予其餘的值

類型註解: 其實就是指定各類類型, boolean, string之類的。其餘語言也叫類型註解 因此統一一下

基礎語法:
變量:類型註解 = 對應類型註解的值  
let bol: boolean = true  
let bol2: boolean  
bol2 =  false
bol = blo2  // 能夠 bol是boolean類型 因此能夠賦值false

bol = ' 1'  //Type '"1"' is not assignable to type'boolean'. 字符串不能賦值給boolean類型
複製代碼

除了規定了變量類型以外,其餘語法與javascript同樣。

數字類型(number)


和JavaScript同樣,TypeScript數字都是浮點型( 1 在JS眼裏是 1.0),也支持二進制、八進制、十進制和十六進制

let num1: number = 123       //十進制 
num1 = 0b01111011            //二進制 0b開頭 ES6引入
num1 = 0o173                 //八進制 0o開頭 ES6引入
num1= 0x7b                   //十六進制 0x開頭

如下是特殊的number類型:
num1 = Infinity              //無窮大
num1 = -Infinity             //負無窮大
num1 = NaN                   //Not a Number
複製代碼

字符串類型(string)


"" ,''和ES6模板字符串\` `.包裹起來的值,都是字符串類型

let str: string = '哈哈哈'
let str2: string = `笑聲${str}`
複製代碼

數組類型(array)


TypeScript 提供了兩種定義數組類型的方法。一種是在類型後加上 []表示這是一個數組。 推薦優先使用這種寫法

語法:
let 變量:類型註解[]

let arr1: number[]  //number類型數組,只能存number類型
arr1 = [5,1,3]   // true
arr1 = ['1']     // false 只能夠賦值number類型
複製代碼

另外一種方法是使用泛型表示:Array < T> ,其中 T 爲數組中元素的類型。

語法:
let 變量:Array<T>  //這裏的 <T> 代指泛型。 能夠簡單的理解爲就是一個佔位符,'暫時'沒有實際的類型。類型根據使用時傳入的值而定。泛型後續會詳解

let arr2 : Array<string> //string 數組
arr = ['1','a','haha']

let arr3 : Array<boolean> = [true,false,true] //boolean數組
複製代碼

元組類型(tuple)


元組類型就是一個特殊的數組。

表示已知數量已知元素類型的數組, 裏面的每一項能夠是不一樣的類型

語法:
let 變量:[類型1,類型2....]

let arr : [string, number, boolean,number[]] 
//1.數量固定,只能傳四個元素,不可少傳也不可多傳
//2.各索引位的元素類型固定,不可改變。

arr = ['1', 2, true, numArr] // true 必須按照 固定數量和類型順序賦值

如下是錯誤寫法:
arr = [1, 2, true, numArr]      //error 第一個位置接收string類型,卻傳入number。類型不匹配
arr = [1, '2', true, numArr]    //error 同上 ,前兩個位置類型不匹配
arr = ['2']                     // error arr必須接受4個參數,這裏只傳入一個
arr = [1, '2', true, numArr, 2] // error 傳入過多的參數也不行,最後一個爲越界元素。如今數組的length爲4,不能傳入第五個值

複製代碼

枚舉類型(enum)


枚舉用來表示一些邏輯上有關聯的數據,而且這些數據不能被修改的。讓這些數據更有語義化。

枚舉類型裏面的值都是隻讀的,只能讀取不能修改

語法:
enum 標識符 {
    值,
    值
    ...
}
------------------------------------------------------
//應用場景:假設根據後臺傳入數據,讓咱們來判斷用戶權限操做
//傳遞的數據裏有id。id存儲的number類型的數據,咱們依次來判斷
roles = {
id:xxx,
...
}

//無語義化寫法:
switch(roles.id) {
    case 0:
        //普通用戶
        break;
    case 1:
        //員工
        break;
    case 2:
        //管理員
        break;
}
//缺點須要寫文檔註釋,代表0 , 1...是什麼意思

//使用枚舉,定義一組用戶數據:
enum Roles {
    USER,   //0
    STAFF,  //1
    ADMIN   //2
}
// 每一個枚舉類型的值,都有對應的索引值,默認從0開始依次遞增
// 取值操做相似於JS對象
Roles.USER // 0 經過屬性取索引
Roles[0] // USER 經過索引取屬性值 下面會解釋是如何實現的

// 使用Roles來做爲判斷條件
switch(roles.id) {
    case Roles.USER:  // 0
        //普通用戶
        break;
    case Roles.STAFF: // 1
        //員工
        break;
    case Roles.ADMIN: // 2
        //管理員
        break;
}
// 更有語義化,代碼直觀易讀
--------------------------------------------------------------------------------------------------------------------
// 將枚舉類型,轉化爲JS。看是如何實現的
enum Roles {
    USER,   //0
    STAFF,  //1
    ADMIN   //2
}

//JS代碼
var Roles;
(function (Roles) {
    Roles[Roles["USER"] = 0] = "USER";
    Roles[Roles["STAFF"] = 1] = "STAFF";
    Roles[Roles["ADMIN"] = 2] = "ADMIN"; 
})(Roles || (Roles = {}));

解析:
首先Roles是個對象,而後當即執行函數會對這個對象進行賦值

Roles[Roles["USER"] = 0] = "USER";
能夠分解爲:
首先給Roles設置一個 USER 的屬性,賦值爲0
Roles["USER"] = 0  //這步操做是有返回值的 返回值就是 = 右邊的值 此處爲0, ~~能夠測試自行建立一個對象,再賦值看返回的結果
而後將上一步的返回值做爲屬性名,再次賦值
Roles[0] = "USER"
因此能夠經過索引或屬性名取相互的值,很是巧妙
Roles[0]  // USER
Roles["USER"] // 0
--------------------------------------------------------------------------------------------------------------------
// 在定義枚舉時,能夠自定義索引值
enum English {
    A = 1,      // 1
    B,          // 2
    D = 4,      // 4
    E           // 5
}

let a = English.A   // 1
let c = English.B   // 2
let d = English.D   // 4
let e = English.E   // 5
let eng = English[5] // E

//自定義索引值只會影響,後續值的索引值(自動根據前一個增長)
enum english {
    a,         // 默認值 0
    b = 2,     // 2 影響排在其後的元素
    c,         // 3 
    d,         // 4
    e          // 5
}

english.a = 1 //error 枚舉類型裏的值是隻讀類型,只容許讀取
english[a] //error 枚舉類型裏面的值,是字符串。這樣取值是錯誤的,會去找同名變量,進行操做。
english['a'] //ok
------------------------------------------------------------------------------------------------------------------
枚舉類型,後續還有不少用法。好比說使用redux時,用來存儲Action的type
複製代碼

any (任意類型)


any表示任意類型,任何值均可以傳入any

any類型 上是類型系統的逃生艙口(走後門)。TS不會對any類型進行檢查

萬物皆any~

let value: any;

value = true;             // OK
value = 42;               // OK
value = "Hello World";    // OK
value = [];               // OK
value = {};               // OK
value = Math.random;      // OK
value = null;             // OK
value = undefined;        // OK
value = new TypeError();  // OK
value = Symbol("type");   // OK
// 如今變量能夠任意賦值,和原生JS平時操做沒有任何限制同樣
--------------------------------------------------------
let anyArr: any[] = [1,24,5,'hhh',['qqq'],true] 

// 雖然方便,但儘可能少使用。否者就失去了使用TS的意義,沒有類型檢查的保障,代碼容易出問題。
// 通常在將JS代碼重構爲TS時,使用的較多
複製代碼

void 類型


void表示沒有任何類型, 經常使用在函數沒有返回值的狀況下指定,表示一個函數沒有返回值

// 例子:
let func = (name:string):void => {
    console.log(`hello, $(name)`)
    // 這個函數沒有指定任何返回值
    // 但在JS裏 函數都會默認返回undefined。void會默認兼容undefined類型
}
func(456) // error 參數必須是是string類型。這就體現了TS的好處了,編譯階段就會提醒錯誤
func('Bob') // true

let num:void 
num = undefined //true 
num = null    //error
num = 1      // error 

let V: any; 
num = V // true 再次強調 any類型能夠兼容其餘全部類型(除never外)~


void 大部分場景用在函數的返回值類型上,關於函數的知識後續會講解
複製代碼

null 和 undefined 類型


1.在TS中null undefined既是類型,也能夠做爲普通的值使用。參考上面函數默認返回值undefined

2.在TS非嚴格模式下nullundefined同時也是其餘類型的子類型(其餘類型能夠兼容這兩個值), 嚴格模式下會報錯

tsconfig.json(ts配置文件):strict: false (非嚴格模式下)(其中一個選項,默認是true 嚴格模式):

let isNull: null  // null類型只能接收 null類型 和 undefined類
let isUndefined: undefined // undefined類型只能接收 undefined類型 和 null類型
isNull = null //true
isNull = 1 //error
isNull = undefined //true
isUndefined = null //true
isUndefined = undefined //true
isUndefined = '2' //error

let str: string
str = null //true
str = undefined //true

--------------------------------------------------------------
tsconfig.json:strict: true (嚴格模式下):

let isNull: null  // null類型只能接收null值
let isUndefined: undefined // undefined類型只能接收undefined值
isNull = null //true
isNull = 1 //error
isNull = undefined //error
isUndefined = null //error
isUndefined = undefined //true
isUndefined = '2' //error

let str: string
str = null //error 嚴格模式下報錯,不能做爲子類型
str = undefined //error

複製代碼

never 類型


never 類型比較抽象,表示永遠不存在的值

非嚴格模式下never類型是任何類型的子類型,也能夠賦值給任何類型.

//常見的兩種狀況 拋出錯誤和死循環 
const errorFunc = (message: string): never => {
    throw new Error(message)
}

const infiniteFunc = ():never => {
    while(true){}
}
------------------------------------------------------
tsconfig.json中:strict: false (非嚴格模式下):

let str: string
let isNever: never
str = isNever // true
isNever = str //error
複製代碼

object 類型


object 類型,就是用來表示引用類型的。與JS對象無差異

let obj = {
    name: 'Bob'
}
obj.sex = 'man'

const getObject = (obj: object):void => { 
    console.log(obj)
}

getObject('hahah') // error
getObject(obj)    // true
複製代碼

類型斷言


混淆是非,把某個值,強制指定爲咱們須要的類型,TS就會按照咱們指定的類型進行檢查

能夠理解爲 相似於強制類型轉換。只是相似┗|`O′|┛ 嗷~~

語法: 兩種寫法。
1. <類型>值 
2.as 類型   //react技術棧 編寫JSX時,必須使用這個。上面的和JSX語法有歧義

// 需求 有個函數接收一個string或者number類型的值。
// 若是是string 咱們直接返回字符串的長度
// 若是是number 我門把number轉化爲字符串,在返回長度

const getLength = (target: string | number): number => {
               // target的類型能夠是string或number. 這是聯合類型的語法。後續會講解
    if(target.length) {  //提示錯誤
        return target.length //提示錯誤
    } else {
        return target.toString().length
    }
}
getLength(1) // 正常
getLength('hh') //正常
// 上面的代碼,邏輯沒有問題。
// 但在TS寫代碼過程當中就會提示錯誤,TS會認爲這個代碼是有問題的。首先編譯階段參數類型還沒肯定,會把number 和 string 都做爲參數類型進行檢測
// string有length屬性能夠經過。number沒有length屬性,因此TS在編譯階段就會提示number沒有length屬性。
// 代碼能正常編譯爲JS,也能正常運行。由於JS是運行時纔會檢測代碼。但一直提示錯誤 屬實很差看

//使用類型斷言解決這個問題。 
const getLength2 = (target: string | number): number => { 
    // 把<string>target,把target指定爲了string類型,這樣代碼就會按照string類型就行檢測。
      if((<string>target).length) { return (target as string).length //同上 類型斷言第二種寫法,加()是由於運算符優先級的問題 } else { return target.toString().length } } getLength2(1) //ok //若是傳入number類型,運行階段仍是會走 toString 那行代碼。 //類型斷言並非說把target轉化爲string類型了。僅僅是在編譯階段 讓TS跟着你指定的類型進行檢測 getLength2('hh') //ok 複製代碼

Symbol 類型的講解推薦去看阮一峯老師的ES6入門教程。TS基本上與ES6沒有多大區別 除了TS擴展的類型~,因此人們常說ES6學好了,學TS會很容易
相關文章
相關標籤/搜索