TS官方文檔筆記

基礎類型

  • 布爾值
let isDone: boolean = false
  • 數(shù)字

和 JavaScript 一樣,TS里所有數(shù)字都是浮點數(shù),類型是 number。除了支持十進制和十六進制字面量,還支持二進制和八進制字面量。

let decLiteral: number = 6
let hexLiteral: number = 0xf00d
let binaryLiteral: number = 0b1010
let octalLiteral: number = 0o744
  • 字符串
let name: string = "bob"

還可以使用模版字符串,它可以定義多行文本和內(nèi)嵌表達式。這種字符串是被反引號包圍,并且以${ expr }這種形式嵌入表達式

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

  • 數(shù)組

有兩種方法定義數(shù)組。第一種,在元素上面接上[],表示由此類型元素組成一個數(shù)組:

let list: number[] = [1, 2, 3]

第二種,使用數(shù)組泛型,Array<元素類型>

let list: Array<number> = [1, 2, 3]
  • 元祖 Tuple

元祖類型允許表示一個已知元素數(shù)量和類型的數(shù)組,各元素類型不必相同。比如,你可以定義一對值分別為stringnumber類型的元祖

// Declare a tuple type
let x: [string, number]
// Initialize it
x = ['hello', 10] // OK
// Initialize it incorrectly
x = [10, 'hello'] // Error
  • 枚舉

默認情況下從0開始為元素編號

enum Color {Red, Green, Blue}
let c: Color = Color.Green

我們也可以手動為元素編號

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2]

console.log(colorName)  // 顯示'Green'因為上面代碼里它的值是2
  • Any

當我們想要為那些在編程階段還不清楚類型的變量指定一個類型,可以使用any類型來標記這些變量

let notSure: any = 4
notSure = "maybe a string instead"
notSure = false // okay, definitely a boolean

在對現(xiàn)有代碼進行改寫的時候,any類型是十分有用的,可以在上面調(diào)用任意的方法

let notSure: any = 4
notSure.ifItExists() // okay, ifItExists might exist at runtime
notSure.toFixed() // okay, toFixed exists (but the compiler doesn't check)

當你只知道一部分數(shù)據(jù)的類型時,any類型也是有用的。 比如,你有一個數(shù)組,它包含了不同的類型的數(shù)據(jù)

let list: any[] = [1, true, "free"]

list[1] = 100
  • Void

某種程度上來說,void類型與any類型相反,它表示沒有任何類型。當一個函數(shù)沒有返回值的時候,你通常會見到其返回值類型是void

function warnUser(): void {
    console.log("This is my warning message")
}

聲明一個void類型的變量沒有什么大用,因為你只能賦予undefinednull

  • Null 和 Undefined

默認情況下,undefinednull是所有類型的子類型

  • Never

never類型表示的是那些用不存在值的類型,never是任何類型的子類型

  • Object

object表示非原始類型,也就是除numberstring,booleansymbol,nullundefined之外的類型

變量聲明

數(shù)組解構賦值

let input = [1, 2]
let [first, second] = input
console.log(first) // outputs 1
console.log(second) // outputs 2

以上代碼使用索引

first = input[0]
second = input[1]

用于已聲名的變量:

// swap variables
[first, second] = [second, first]

作用于函數(shù)

let input = [1, 2]
function f([first, second]: [number, number]) {
    console.log(first)
    console.log(second)
}
f(input)

在數(shù)組中使用...語法創(chuàng)建剩余變量

let [first, ...rest] = [1, 2, 3, 4]
console.log(first) // outputs 1
console.log(rest) // outputs [ 2, 3, 4 ]

當然,也可以忽略尾隨元素

let [first] = [1, 2, 3, 4]
console.log(first) // outputs 1
  • 對象解構
let o = {
    a: "foo",
    b: 12,
    c: "bar"
}
let { a, b } = o

上面代碼通過o.ao.b創(chuàng)建了ab
可以在對象里使用...語法創(chuàng)建剩余變量

let { a, ...passthrough } = o
let total = passthrough.b + passthrough.c.length
  • 屬性命名
let { a: newName1, b: newName2 } = o

方向從左至右,可以像以下代碼一樣理解

let newName1 = o.a
let newName2 = o.b

需要注意的是這里,這里冒號不是指示類型。如果想要指定類型,仍需在后面寫上完整的模式

let {a, b}: {a: string, b: number} = o
  • 展開
    展開操作符與解構相反
let first = [1, 2]
let second = [3, 4]
let bothPlus = [0, ...first, ...second, 5]

上面代碼令bothPlus的值為[0,1,2,3,4,5]。展開操作創(chuàng)建了firstsecond的一份淺拷貝,不會被展開操作所改變。
不建議展開對象

接口

TypeScript的核心原則之一是對所具有的結構進行類型檢查。
在TypeScript里,接口的作用就是為了這些類型命名和為你的代碼或第三方代碼訂立契約。
接口是如何工作的:

function printLabel(labelledObj: { label: string }) {
  console.log(labelledObj.label)
}

let myObj = { size: 10, label: "Size 10 Object" }
printLabel(myObj);

類型檢查器會查看printLabel的調(diào)用。printLabel有一個參數(shù),并要求這個對象參數(shù)有一個名為label類型為string的屬性。需要注意的是,我們傳入的對象參數(shù)實際上會包含很多屬性,但是編譯器只會檢查那些必須的屬性是否存在,并且其類型是否匹配。
下面用接口描述上面的例子(必須包含一個label屬性且類型為string):

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

LabelledValue接口就好比一個名字,用來描述上面例子里的要求。它代表了有一個label屬性且類型為string的對象。在這里只關注值的外形。只要傳入對象滿足接口,那么它就是被允許的。
類檢查器不會檢查屬性的順序,只要相應的屬性存在即可。

  • 可選屬性

接口里的屬性不全都是必須的。有些是只在某些條件下存在,或者根本不存在。 可選屬性在應用“option bags”模式時很常用,即給函數(shù)傳入的參數(shù)對象中只有部分屬性賦值了。
下面是應用了“option bags“的例子:

interface SquareConfig{
  color?: string
  width?: number
}

funcrtion createSquare(config:SquareConfig):{color: string; area: number}{
  let newSquare =  {color: "white"; area: 100}
  if(config.color){
    newSquare.color = config.color
  }
  if(config.width){
    newSquare.area = config.width * config.width
  }
  return newSquare
}
let mySquare = createSquare({color: "black"})

帶有可選屬性的接口與普通接口的定義差不多,只是在可選屬性名字定義后面加上一個?符號
可選屬性的好處之一是可以對可能存在的屬性進行預定義,好處之二是可以捕獲引用了不存在的屬性時的錯誤。比如,故意將屬性名字拼錯,就會得到一個錯誤提示。

  • 只讀屬性

一些對象屬性只能在對象剛剛創(chuàng)建的時候修改其值??梢栽趯傩悦坝?code>readonly來指定只讀屬性:

interface Point {
  readonly x: number
  readonly y: number
}

可以通過賦值一個對象字面量來構造一個Point。賦值后,xy再也不能被改變

let p1: Point = {x:10, y: 20}
p1.x = 5 //error

TypeScript具有Readonly<T>類型,確保數(shù)組創(chuàng)建后再也不能被修改:

let a: number[] = [1,2,3,4]
let ro: ReadonlyArray<number> = a
ro[0] = 12 // error
ro.push(5) // error
ro.length = 100 // error
a = ro // error

上面的最后一行,就算是把整個ReadonlyArray賦值到一個普通數(shù)組也不可以。但是可以用類型斷言重寫:

a = ro as number[]
  • 函數(shù)類型

為了使用接口表示函數(shù)類型,需要給接口定義一個調(diào)用簽名。它就像是一個只有參數(shù)列表和返回值類型的函數(shù)定義。參數(shù)列表里的每個參數(shù)都需要名字和類型

interface SearchFunc {
  (source: string, subString: string): boolean;
}

下例展示了如何創(chuàng)建一個函數(shù)類型的變量,并將一個同類型的函數(shù)賦值給這個變量

let mySearch: SearchFunc
mySearch = function(source: string, subString: string){
  let result = source.search(subString)
  return result > -1
}

對于函數(shù)類型的類型檢查來說,函數(shù)的參數(shù)名不需要與接口里定義的名字相匹配:

let mySearch: SearchFunc
mySearch = function(src: string, sub:string){
  let result = src.search(sub)
  return result > -1
}

持續(xù)更新中。。。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容