TypeScript(四) —— 函數(shù)/接口/類/泛型語法總結(jié)

目錄

  • 函數(shù)類型
    • 函數(shù)聲明
    • 函數(shù)類型表達式
    • 可選參數(shù)
    • 任意個數(shù)的參數(shù)
  • 接口(interface)
    • 定義接口
    • 使用接口
    • 選成員 & 只讀成員 & 動態(tài)成員
    • 需要對類的屬性與方法進行聲明
    • 類成員訪問修飾符(public/private/protected)
        1. 定義一個構(gòu)造函數(shù)
        1. 初始化實例對象并訪問構(gòu)造函數(shù)成員
        1. 創(chuàng)建子類繼承構(gòu)造函數(shù)并訪問其成員
    • 類的構(gòu)造函數(shù)被私有化
    • 類的只讀屬性
    • 類與接口
      • 定義接口
      • 實現(xiàn)接口
    • 抽象類
      • 抽象類定義
      • 子類繼承
  • 泛型
    • 定義泛型參數(shù)
    • 調(diào)用時傳入泛型參數(shù)的類型
  • TypeScript學習地圖

函數(shù)類型

函數(shù)的輸入和輸出進行約束亩进,及參數(shù)和返回值

函數(shù)聲明

// 參數(shù)的類型和返回值的類型
function func1(a: number, b: number): string {
    return 'func1'
}
// 參數(shù)類型和個數(shù)是固定的灵汪,否則報錯
func1(100, 200)

函數(shù)類型表達式

// 普通函數(shù)
const func4 = function (a: number, b: number): string {
    return 'func2'
}
// 使用箭頭函數(shù)
const func5: (a: number, b:number) => string = function(a, b) {
    return 'func2'
}

可選參數(shù)

可選參數(shù)一定要在必選參數(shù)后面牺汤,放在函數(shù)最后咳短。

// 可以在b后面添加問號表示可選,也可以直接設置默認值评也,也可以不用傳
function func2(a: number, b: number = 10, c?: number): string {
    return 'func1'
}

func1(100)

任意個數(shù)的參數(shù)

使用ES6rest操作符

function func3(a: number, b: number = 10, ...rest: number[]): string {
    return 'func1'
}

func1(100,200,300,400)

接口(interface)

接口攒磨,是一種規(guī)范、契約蜗字,約定對象的結(jié)構(gòu)打肝。

接口是用來約束一個對象的結(jié)構(gòu),我們要使用這個接口挪捕,就要遵循其全部的約定粗梭。

接口最直觀的體現(xiàn)就是對象應該有哪些成員以及成員的類型都是什么樣的?

定義接口

// 定義一個接口,里面確定要有兩個成員级零,且都是字符串類型
interface Post {
  title: string  // 結(jié)尾可以使用逗號分隔断医,也可以使用分號去分割,還可以省略
  content: string
}

使用接口

// 使用的時候聲明參數(shù)是Post類型奏纪,里面使用的時候不擔心沒有值
function printPost (post: Post) {
  console.log(post.title)
  console.log(post.content)
}

// title和content任何一個沒有傳或者不是字符串都會報錯
printPost({
  title: 'this is a title',
  content:'this is a content'
})

可選成員 & 只讀成員 & 動態(tài)成員

  • 可選成員 : 定義接口的時候添加問號鉴嗤,傳參的時候可有可無
interface Post {
  title: string
  content: string
  subtitle?: string // 可選成員,可有可無,string or undefined
}

// 下面不傳subtitle不會報錯
const hello: Post = {
    title: 'this is a title',
    content:'this is a content'
}
  • 只讀成員 :定義接口的時候前面添加readonly關(guān)鍵詞序调,一經(jīng)定義不能修改
interface Post {
  title: string
  content: string
  subtitle?: string
  readonly summary: string //只讀成員醉锅,一經(jīng)定義不能更改
}

const hello: Post = {
    title: 'this is a title',
    content:'this is a content',
    summary: 'this is a summary'
}

hello.summary = 'hello' // 報錯
  • 動態(tài)成員 :不確定有哪些成員,自己定義添加发绢,一般這種都存在動態(tài)對象里面硬耍,例如程序中的緩存對象。

因為不知道有哪些成員名稱边酒,所以Cache里面使用[]经柴,指定鍵prop的類型是string,值的類型是number

interface Cache {
  [prop: string] : number
}

const cache: Cache = {}

cache['hello'] = 1
cache['hi'] = 2

類用來描述一類具體事物的抽象特征甚纲。TypeScript增強了class的相關(guān)語法口锭,訪問修飾符以及抽象類的概念等...

下面看一下TypeScript新增的內(nèi)容:

需要對類的屬性與方法進行聲明

目的是為了給屬性和方法做類型標注

class Person {
  // 需要對類的屬性進行聲明,可以添加默認值介杆,也可以不添加
  // 兩者有一個沒有寫鹃操,都會報錯
  name: string = 'init name'
  age: number
  
  constructor (name: string, age: number) {
    // 如果不加聲明,這里直接使用會報錯春哨,因為在TypeScipt需要明確屬性荆隘,而不是動態(tài)添加
    this.name = name
    this.age = age
  }
  
  // 方法這些和之前是一樣的,也要添加類型注解
  sayHi (msg: string): void {
    console.log(`I am ${this.name}, ${msg}`)
  }

  run (): void {
    this.sayHi('I am happy!')
  }
}

類成員訪問修飾符(public/private/protected)

- public private protected
內(nèi)部訪問
外部訪問 不可 不可
子類訪問 不可

1. 定義一個構(gòu)造函數(shù)

class Person {
  // 默認是public赴背,加不加效果一樣椰拒,建議去加
  public name: string = 'init name'
  // age屬性是個私有屬性晶渠,私有屬性可以在函數(shù)內(nèi)部通過this.age去訪問
  private age: number
  // 受保護的,外界成員不可訪問燃观,子類成員可以訪問
  protected gender: boolean

  constructor (name: string, age: number) {
    this.name = name
    this.age = age
    this.gender = true
  }

  sayHi (msg: string): void {
    console.log(`I am ${this.name}, ${msg}`)
    console.log(this.age) //自己內(nèi)部訪問私有屬性是沒有問題的
    console.log(this.gender) //自己內(nèi)部訪問受保護屬性是沒有問題的
  }
}

2. 初始化實例對象并訪問構(gòu)造函數(shù)成員

const xm = new Person('xm', 18)
console.log(xm.name)
console.log(xm.age) // 報錯褒脯,Property 'age' is private and only accessible within class 'Person'
console.log(xm.gender) // 報錯,Property 'gender' is protected and only accessible within class 'Person' and its subclasses.

3. 創(chuàng)建子類繼承構(gòu)造函數(shù)并訪問其成員

//定義一個Student類繼承Person
class Student extends Person {
  constructor(name: string, age: number) {
    super(name, age)
    console.log(this.gender)
    console.log(this.age) // 報錯缆毁,私有成員不能訪問
    console.log(this.name)
  }
}

類的構(gòu)造函數(shù)被私有化

  • private: 如果類的構(gòu)造函數(shù)被私有化番川,那么不能被實例化和繼承,這個時候只能在這個類的內(nèi)部添加一個靜態(tài)方法脊框,通過靜態(tài)方法添加實例颁督。
  • protected: 如果類的構(gòu)造函數(shù)被受保護,那么不能實例化浇雹,但是可以繼承沉御。
class Student extends Person {
  private constructor(name: string, age: number) {
    super(name, age)
    console.log(this.gender)
    console.log(this.name)
  }
  // 可以定義一個方法內(nèi)部實例化
  static create (name: string, age: number) {
    return new Student(name, age)
  }
}

const xm = Student.create('xm', 18)
console.log(xm.name)

類的只讀屬性

在屬性前添加修飾符readonly,如果有訪問修飾符昭灵,那么就跟在修飾符的后面.只讀屬性必須在聲明時或構(gòu)造函數(shù)里被初始化吠裆。

class Person {
  public name: string = 'init name'
  private age: number
  // 如果有訪問修飾符,那么就跟在修飾符的后面
  protected readonly gender: boolean

  constructor (name: string, age: number) {
    this.name = name
    this.age = age
    this.gender = true
  }

  sayHi (msg: string): void {
    console.log(`I am ${this.name}, ${msg}`)
    console.log(this.gender = false) // Cannot assign to 'gender' because it is a read-only property.
  }

  run (): void {
    this.sayHi('I am happy!')
  }
}

let xm = new Person('xm', 18)
xm.gender = 'false' // 報錯

類與接口

類與類之間的公共特征一般會用接口去抽象

比如下面兩個不同的類烂完,但是都有eatrun兩個相同的方法硫痰,可以用接口約束兩個類中公共的部分

class Person {
  eat (food: string): void {
    console.log(`優(yōu)雅進餐:${food}`)
  }

  run (distance: number) {
    console.log(`直立行走:${distance}`)
  }
}

class Animal {
  eat (food: string): void {
    console.log(`不優(yōu)雅進餐:${food}`)
  }

  run(distance: number) {
    console.log(`爬行:${distance}`)
  }
}

定義接口

// 可以定義一個接口實現(xiàn)一個能力,然后讓一個類實現(xiàn)多個接口

interface Eat {
  eat (food: string): void
}

interface Run {
  run (distance: number): void
}

實現(xiàn)接口

// Person和Animal要實現(xiàn)接口窜护,如果里面少了接口對應的方法,就會報錯效斑。
class Person implements Eat, Run{
  eat (food: string): void {
    console.log(`優(yōu)雅進餐:${food}`)
  }

  run (distance: number) {
    console.log(`直立行走:${distance}`)
  }
}

class Animal implements Eat, Run{
  eat (food: string): void {
    console.log(`不優(yōu)雅進餐:${food}`)
  }

  run(distance: number) {
    console.log(`爬行:${distance}`)
  }
}

抽象類

  • 抽象類與接口有些類似,也是約束子類中必須要有哪些成員柱徙,不同的是抽象類里面可以包含一些具體的實現(xiàn)
  • 抽象類只能繼承缓屠,不能實例化對象
  • 抽象類中可以定義一些抽象方法
  • 抽象方法不需要方法體,當父類中有抽象方法的時候护侮,子類必須要實現(xiàn)抽象方法

抽象類定義

// 添加abstract關(guān)鍵詞之后就成為了抽象類
abstract class Animal {
  eat (food: string): void {
    console.log(`不優(yōu)雅進餐:${food}`)
  }
  // 抽象類中可以定義一些抽象方法敌完,也需要關(guān)鍵詞abstract
  abstract run (distance: number): void
}

子類繼承

class Dog extends Animal {
  // 可以在VSCode環(huán)境點擊Dog使用快速修復自動生成代碼實現(xiàn)
  // 這里實現(xiàn)了抽象類中的run抽象方法
  run(distance: number): void {
    console.log('爬行', distance)
  }
}

// 子類實例化
const d = new Dog()
d.eat('糧食')
d.run(100)

泛型

我們在定義函數(shù)、接口或者類的時候沒有去指定類型羊初,只有當使用的時候才去指定類型的一種特征滨溉。

其目的 就是為了極大程度復用我們的代碼

舉個例子:

下面是傳入長度和值,返回一個數(shù)組

// 參數(shù)長度是number類型长赞,value是number類型晦攒,返回的是number類型的數(shù)組
function createArray (length: number, value: number): number[] {
  const arr = Array<number>(length).fill(value)
  return arr
}

// 下面?zhèn)魅雲(yún)?shù)可以獲得三個值為100的數(shù)字類型的數(shù)組
const res = createArray(3, 100) // res => [100, 100, 100]

上面的代碼有個缺陷是只能返回數(shù)字類型的數(shù)組,如果換成其他類型就會報錯得哆,如何進行修改?

定義泛型參數(shù)

  • 函數(shù)名后面使用尖括號脯颜,里面定義泛型參數(shù)
  • 一般泛型參數(shù)都用大寫的T作為名稱,函數(shù)中不明確的類型都用T去代表
function createArray <T> (length: number, value: T): T[] {
  const arr = Array<T>(length).fill(value)
  return arr
}

調(diào)用時傳入泛型參數(shù)的類型

  • 調(diào)用時在函數(shù)名后面用尖括號內(nèi)部填入?yún)?shù)的類型
// 下面可以填充字符串類型或者數(shù)字類型都可以
const res = createArray<string>(3, 'foo')
const res1 = createArray<number>(3, 100)

總結(jié) 就是泛型參數(shù)將定義時不能明確的參數(shù)用一個T來代替贩据,使用的時候指定T的類型

TypeScript學習地圖

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末栋操,一起剝皮案震驚了整個濱河市闸餐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌矾芙,老刑警劉巖舍沙,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剔宪,居然都是意外死亡场勤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門歼跟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人格遭,你說我怎么就攤上這事哈街。” “怎么了拒迅?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵骚秦,是天一觀的道長。 經(jīng)常有香客問我璧微,道長作箍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任前硫,我火速辦了婚禮胞得,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屹电。我一直安慰自己阶剑,他們只是感情好,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布危号。 她就那樣靜靜地躺著牧愁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪外莲。 梳的紋絲不亂的頭發(fā)上猪半,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音偷线,去河邊找鬼磨确。 笑死,一個胖子當著我的面吹牛声邦,可吹牛的內(nèi)容都是我干的俐填。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼翔忽,長吁一口氣:“原來是場噩夢啊……” “哼英融!你這毒婦竟也來了盏檐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤驶悟,失蹤者是張志新(化名)和其女友劉穎胡野,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痕鳍,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡硫豆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了笼呆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熊响。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖诗赌,靈堂內(nèi)的尸體忽然破棺而出汗茄,到底是詐尸還是另有隱情,我是刑警寧澤铭若,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布洪碳,位于F島的核電站,受9級特大地震影響叼屠,放射性物質(zhì)發(fā)生泄漏瞳腌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一镜雨、第九天 我趴在偏房一處隱蔽的房頂上張望嫂侍。 院中可真熱鬧,春花似錦荚坞、人聲如沸吵冒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痹栖。三九已至,卻和暖如春瞭空,著一層夾襖步出監(jiān)牢的瞬間揪阿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工咆畏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留南捂,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓旧找,卻偏偏與公主長得像溺健,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钮蛛,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容