typeScript-基礎篇(二)

  • 建議先從 typeScript從入門到進階-基礎篇(一)開始學習, 基礎(一)是一個ts初體驗,走完這個流程你本地就擁有了ts的相關環境和編譯工具,能夠進行下面的語法測試;html

  • 或者也能夠在 ts在線編譯地址 裏面進行下面的語法測試;typescript

基本類型

ES6的數據類型 TS的數據類型
Boolean Boolean
Number Number
String String
Array Array
Function Function
Object Object
Symbol Symbol
undefind undefind
null null
- void
- any
- never
- 元組
- 枚舉
- 高級類型
類型註解
  • 做用:至關於強類型語言中的類型聲明
  • 語法:(變量/函數):type
// 原始類型
let bool: boolean = true
let num: number = 124
let str: string = 'abc'

// 數組
let arr1 = number[] = [1, 2, 3]
let arr2 = Array<number> = [1, 2, 3]
let arr3 = Array<number | string> =  [1, 2, 3, '4']

// 元組 一種特殊的數組,限定了元素的類型和個數
let tuple: [number, string ] = [0, '1']
// 元組的越界問題:
tuple.push(2)  
console.log(tuple) // [0, '1', 2]
tuple[2]  // 報錯不能訪問,開發時不建議這樣作

// 函數
let add = (x: number, y: number): number => x + y
let add = (x: number, y: number) => x + y // 返回值類型number能夠省略

let compute: (x: number,y: number) => number // 函數類型的定義
compute = (a, b) =>  a + b // 函數的實際定義中,形參能夠和定義不同,也能夠不用指定具體類型
   
// 對象
let obj: {x: number, y: number} = {x: 1, y: 2}
obj.x = 3

// symbol 具備惟一的值
let s1: symbol = Symbol()
let s2 = Symbol()
console.log(s1 === s2 ) // false

// undefind, null
// 一旦被賦值成undefind 就不能再賦值任何類型了

let un: undifind = undefind
let nu: null = null 

// 在ts官方的文檔中,undefind 和 null 是任何類型的子類型,說明能夠被賦值成其餘類型
// 這裏須要作一些設置:
// 在tsconfig.json  設置"strictNullChecks": false,就容許賦值了
// 可是須要注意: 聲明須要加上null和undefind才能經過類型檢查
let num: number | null | undefind = 124

// void
// 在ts中,void 表示一種沒有任何返回值的類型
// 在js中,void 是一種操做符,可讓任何表達式返回undefind 

let noReturn = () => {} // 一個沒有任何返回值的函數

void 0 // undefind  爲何會有這種操做?
// 在js中,undefind不是一個保留字,咱們甚至能夠自定義一個undefind去覆蓋全局的undefind;
(function() {
    var undefind = 0
    console.log(undefind)
})()


// any 
在ts中不指定變量的類型,默認就是any類型,不建議使用any
let x
x = 1
x = []
x = '2'

// never
// 表示永遠不會有返回值的類型
let error = () => {  // 函數拋出異常
    throw new Error('error')
}
let endLess = () => { // 死循環函數
    while(true){}
}
枚舉類型

一組有名字的常量集合json

  • 枚舉成員的值是隻讀類型的,一旦定義了不能修改
  • 實現原理:反向映射,枚舉被編譯成了一個對象,枚舉成員的名稱被做爲了key,枚舉成員的值被做爲了value,value又做爲key,成員的名稱又被做爲value;
  • 適用狀況:將程序中不容易記憶的硬編碼,或者在將來可能改變的常量抽取出來,定義成枚舉類型,能夠提升程序的可讀性和可維護性
enum {
    Reporter = 1,
    Developer
}

最終被編譯成:
"use strict"
var Role;
(function(Role){
    Role[Role["Reporter"] = 1] = "Reporter"];
    Role[Role["developer"] = 1] = "developer"];
}
)(Role || {Role = {})
// 數字枚舉
enum {
    Reporter = 1, // 能夠給默認值
    Developer
}

// 字符串枚舉(不能進行反向映射)
enum Message {
    Success = "恭喜,恭喜",
    Fail = "再接再礪"
}

// 異構枚舉 (容易引發混淆,不建議使用)
enum Answer {
    N,
    Y = 'yse'
}

// 枚舉成員
類型:1.const 常量枚舉,常量枚舉會在編譯時計算出結果,而後以常量的形式出如今運行時環境
        包括三種狀況: 
        - 沒有初始值的狀況
        - 對已有枚舉成員的引用
        - 常量的表達式
      2.computed number,必定要被賦予初始值;
      須要被計算的枚舉成員,很是量的表達式,不會再編一階段進行計算,而會保留到程序的執行階段
enum Char {
    // const
    a,  
    b =  Char.a, 
    c = 1 + 3,
    // computed
    d = Math.random(),
    e = '123'.length
}

// 常量枚舉:用const聲明的枚舉,在編譯階段會被移除
    - 當不須要對象,只須要一個對象的值的時候能夠用常量枚舉
const enum Month = {
    Jan,
    Feb,
    Mar
}
let month = [Month.Jan, Month.Feb, Month.Mar]

// 枚舉類型
// - 在某些狀況下,枚舉和枚舉成員均可以做爲一種單獨的類型存在
enum E { a, b }  // 沒有初始值
enum F { a = 0, b = 1 } // 全部初始值都是數字枚舉
enum G { a = 'apple', b = 'banana' } // 全部初始值都是字符串枚舉

let e: E = 3  // 能夠把任意的number類型賦值給枚舉類型,它的取值也能夠超出枚舉成員的定義
let f: F = 3
e === f // 報錯;兩種不一樣的枚舉類型成員是不能夠比較的

let e1: E.a === 1
let e2: E.b 
e1 === e2 //  報錯;兩種不一樣的枚舉類型成員是不能夠比較的
let e3: E.a === 1
e1 === e3 // true 相同的枚舉類型成員能夠比較

let g1: G = G.a // 字符串枚舉的取值必須是枚舉成員的類型
let g2: G.a = G.A // 只能是自身

接口

對象類型接口
  • 接口能夠用來約束對象,函數,類的結構和類型,是一種代碼協做的契約,必須遵照,且不能改變;
interface List {
    id: number,
    name: string
}
interface Result {
    data: List[]
}

function render(result: Result){
    result.data.forEach((value) => {
        console.log(value.id,value.name)
    })
}

let result = {  // 假設result是從後端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要知足要求,傳入多餘的字段也能夠經過類型檢查
        {id: 2, name: 'B'}
    ]
}

render(result)  // 沒毛病
// 用對象字面量的方式ts會報錯
render({  // 假設result是從後端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要知足要求,傳入多餘的字段也能夠經過類型檢查
        {id: 2, name: 'B'}
    ]
})

繞過這種檢查的方式有三種:
1.將對象字面量賦值給一個變量,如上;
2.使用類型斷言, as Result,或在前面加上<Result>
    - 這兩種方法是等效的,建議使用第一種方法,<Result>在React會產生歧義
明確的告訴編譯器,傳入的對象類型就是Result,這樣編譯器就會繞過類型檢查
render({  // 假設result是從後端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要知足要求,傳入多餘的字段也能夠經過類型檢查
        {id: 2, name: 'B'}
    ]
} as Result)

render(<Restul>{  // 假設result是從後端返回的接口
    data: [
        {id: 1, name: 'A', sex: 'male'}, // 只要知足要求,傳入多餘的字段也能夠經過類型檢查
        {id: 2, name: 'B'}
    ]
})

3.使用字符串索引簽名
interface List {
    id: number,
    name: string,
    [x: string]: any  // 字符串索引簽名, 含義是:用任意的字符串去索引List,能夠獲得任意的結果,這樣List能夠支持多個屬性了
}

接口成員屬性:後端

1. 可選屬性,屬性後加 ?
interface List {
    id: number,
    name: string,
    age?: number  // 無關緊要
}
2. 只讀屬性
interface List {
    readonly id: number, // id通常是隻讀屬性
    name: string
}

可索引類型的接口數組

  • 在不肯定接口返回來的屬性的個數,就可定義可索引類型的接口,能夠用數字去索引,也可用字符串去索引
// 數字索引類型的接口
interface StringArray {
    [index: number]: string  // 用任意的數字去索引stringArray,都會獲得一個string,就至關於聲明瞭一個字符串類型的數組
}
// 字符串索引類型的接口
interface Names {
    [x: string]: string; // 用任意字符串去索引Names,獲得的都是一個string,這樣聲明後,就不能聲明number類型的成員了
    // y: number;  // 不被容許
}
兩種索引簽名是能夠混用的:
interface Names {
    [x: string]: string, // [x: string]: any,
    [z: number]: string  // 注意:數字索引簽名的返回值必定要是字符串索引簽名返回值的子類型,由於js會進行類型轉換,將number轉換成string,這樣就能保持類型的兼容性
}
相關文章
相關標籤/搜索