筆記四:TypeScript語言

一度气、JavaScript

1.弱類型鄙漏、動態(tài)語言的缺陷

  • 程序中的異常在運行時才能發(fā)現(xiàn)
  • 類型不明確函數(shù)功能會發(fā)生改變
  • 對對象索引器的錯誤用法

2.強類型的優(yōu)勢

  • 錯誤更早暴露
  • 代碼更智能,編碼更準確
  • 重構(gòu)更牢靠
  • 減少不必要的類型判斷

二红符、Flow

1.Flow是JavaScrpt類型檢查器

// : number 叫做類型注解
function sum (a: number, b: number) {
  return a + b
}
console.log(sum(1, 2))

2.如何安裝并使用flow

  • 先執(zhí)行yarn init -y
  • 執(zhí)行yarn add flow-bin
  • 在代碼中第一行添加flow注釋://@flow
  • 在函數(shù)中形參后面加上冒號和類型 function sum(a:number赞弥, b: number)
  • 執(zhí)行yarn flow init 創(chuàng)建flowconfig
  • 執(zhí)行yarn flow
// @flow
// : number 叫做類型注解
function sum (a: number, b: number) {
  return a + b
}
console.log(sum(1, 2))

console.log(sum('100', '100'))

3.如何移除flow注解

flow官方提供的操作

  • yarn add flow-remove-types --dev
  • yarn flow-remove-types src -d dist
    使用babel配合flow轉(zhuǎn)換的插件
  • yarn add @babel/core @babel/cli @babel/preset-flow --dev
  • babel文件
{
    "presets":["@babel/preset-flow"]
}
  • yarn babel src -d dist

4.開發(fā)工具插件

5.Flow支持的類型

/**
 * 原始類型
 * @flow
 */

 const a: string = 'foo'

 const b: number = Infinity // NaN // 100

 const c: boolean = false // true

 const d: null = null

 const e: void = undefined

 const f: symbol = Symbol()

 const arr: Array<number> = [1, 2, 3]

 const arr2: number[] = [1, 2, 3]

 // 元組
 const foo: [string, number] = ['foo', 100]

const obj1: {foo: string, bar: number} = {foo: 'string', bar: 100}

// 問號表示可有可與的屬性
const obj2: {foo?: string, bar: number} = {bar: 100}

// 表示當(dāng)前對象可以添加任意個數(shù)的鍵,不過鍵值的類型都必須是字符串
const obj3: {[string]: string} = {}
obj3.key1 = 'value1'
// obj3.key2 = 100

function fn (callback: (string, number) => void) {
  callback('string', 100)
}

fn(function (str, n) {

})

const fo: 'foo' = 'foo'

// 聯(lián)合類型阵漏,變量的值只能是其中之一
const type: 'success' | 'warning' | 'danger' = 'success'

// 變量類型只能是其中的一種類型
const g: string | number = 100

type StringOrNumber = string | number
const h: StringOrNumber = 'stri' // 100

// maybe類型 加一個問號驻民,變量除了可以接受number類型以外,還可以接受null或undefined
const gender: ?number = null
// 相當(dāng)于
// const gender: number | null | void = undefined

// Mixed / Any  mixed是強類型履怯,any是弱類型回还,為了兼容老代碼,是不安全的叹洲,盡量不用any
// string | number | boolean |...
function passMixed (value: mixed) {

}
passMixed('string')
passMixed(100)

function passAny (value: any) {

}
passAny('string')
passAny(100)

const element: HTMLElement | null = document.getElementById('root')

6.運行環(huán)境API

三柠硕、TypeScript

TypeScript:JavaScript超集/擴展集

1.安裝并使用typescript模塊

  • yarn add typescript --dev
  • 創(chuàng)建一個擴展名為ts的文件,myTypeScript.ts:
// TypeScript 可以完全按照JavaScript 標準語法編碼
const hello = (name: string) => {
  console.log(`hello, ${name}`)
}

hello('TypeScript')
// hello(111)
  • 執(zhí)行yarn tsc myTypeScript.ts运提,會生成一個同名的js文件
  • 查看myTypeScript.js
// TypeScript 可以完全按照JavaScript 標準語法編碼
var hello = function (name) {
    console.log("hello, " + name);
};
hello('TypeScript');
// hello(111)

2.tsc命令的作用

tsc:(typescript compiler) 編譯ts文件: 執(zhí)行命令yarn tsc myTypeScript.ts

  • 檢查類型使用異常
  • 移除注解之類的擴展語法
  • 自動轉(zhuǎn)換ECMAScript的新特性
    tsc編譯整個項目:
  • 執(zhí)行命令yarn tsc --init,生成tsconfig.json文件
  • 執(zhí)行命令yarn tsc, 按照配置文件將src中的ts文件生成到了dist中的js文件蝗柔,并且是采用ES2015語法

3.TS支持的原始類型

const a: string = 'foobar'

const b: number = 100 // NaN Infinity

const c: boolean = true // false

// const d: boolean = null // 嚴格模式下不支持賦值null

const e: void = undefined // 函數(shù)沒有返回值時的返回值類型

const f: null = null

const g: undefined = undefined

const h: symbol = Symbol()

4.TS標準庫聲明

標準庫就是內(nèi)置對象所對應(yīng)的聲明
在tsconfig.json中寫上:

"lib": ["ES2015", "DOM"], 

5.錯誤消息中文顯示設(shè)置

yarn tsc --locale zh-CN

6.作用域

每個文件都是全局作用域,所以在不同文件中定義同名變量會報錯民泵,解決方案:

  • 使用立即執(zhí)行函數(shù)癣丧,產(chǎn)生作用域
(function () {
  const a = 123
} )()
  • 使用export
const a = 11
export {} // 確保跟其他實例沒有成員沖突

7.Object類型

TypeScript中的Object類型泛指所有的的非原始類型。如對象栈妆、數(shù)組胁编、函數(shù).
object類型并不單指對象,而是指除了原始類型之外的其他類型.
對象的賦值必須與定義的屬性保持一致鳞尔,不能多也不能少嬉橙。更專業(yè)的寫法是用接口.

export {} // 確保跟其他實例沒有成員沖突

const foo: object = function () {} // [] // {} 

const obj: {foo: number, bar: string} = {foo: 123, bar: 'string'} 

const arr1: Array<number> = [1, 2, 3]

const arr2: number[] = [1, 2, 3]

function sum (...args: number[]) {
  return args.reduce((prev, current) => prev + current, 0)
}
sum(1, 2, 3)

8.元組類型

固定長度的數(shù)據(jù)。 例如Object.entries(obj)的返回值里面的每一個元素都是一個元組

export {}

const tuple: [number, string] = [19, 'jal']
// 下標取值
// const age = tuple[0]
// const name = tuple[1]

// 數(shù)組解構(gòu)
const [age, name] = tuple

9.枚舉類型

// JS中沒有枚舉類型铅檩,則使用對象模擬枚舉類型
// const PostStatus = {
//   Draft: 0,
//   Uppublished: 1,
//   Published: 2
// }

// 枚舉類型憎夷。使用時和對象屬性一樣
// 如果不指定值,則從0開始累加昧旨。如果制定了第一個成員的值拾给,后面的成員則再第一個成員基礎(chǔ)上累加。值如果是字符串兔沃,就得指定具體的值
const enum PostStatus {
  Draft = 0, 
  Uppublished = 1,
  Published = 2
}

const post = {
  title: 'Hello TypeScript',
  content: 'Type...',
  status: PostStatus.Draft
}

10.函數(shù)類型

// 獲取不確定參數(shù)
// function func1 (a: number, b: number): string {
// function func1 (a: number, b?: number): string {
// function func1 (a: number, b: number = 10): string {
function func1 (a: number, b: number = 10, ...rest: number[]): string {
  return 'func1'
}

func1(100, 200)

func1(100)

func1(100, 200, 300)

// 指定函數(shù)的形式
const func2: (a: number, b: number) => string = function (a: number, b: number ): string {
  return 'f'
}

11.任意類型

any類型是為了兼容老的代碼蒋得,它還是動態(tài)類型,是不安全的乒疏,盡量少用

function stringify (value: any) {
  return JSON.stringify(value)
}

stringify('string')
stringify(100)
stringify(true)

let foo: any = 'string'
foo = 100

foo.bar()

12.隱式類型推斷

let age = 18 // ts推斷出類型是number
// age = 'str' // 會報錯 不能將類型“"str"”分配給類型“number”额衙。

let foo // 此時無法推斷具體類型,foo則是動態(tài)類型,any類型
foo = 1 // 不會報錯
foo = 'string' // 不會報錯

13.類型斷言

const nums = [110, 120, 119, 112]

const res = nums.find(i => i>0)
// const res: number | undefined
// const square = res * res

const num1 = res as number // 斷言 res 是number
const square = num1 * num1
const num2 = <number>res // 或者這種方式窍侧。JSX下不能使用

14.接口

// 可以用分號分割县踢,分號可以省略
interface Post {
  title: String
  content: String
}

function printPost (post: Post) {
  console.log(post.title)
  console.log(post.content)
}

printPost({
  title: 'hello',
  content: 'javascript'
})

可選屬性、只讀屬性

interface Post {
  title: String
  content: String
  subtitle?: string // 可有可無的屬性伟件。也就是說該屬性為string或者undefined
  readonly summary: string
}

const hello: Post = {
  title: 'hello',
  content: 'javascript',
  summary: 'js'
}

//報錯: Cannot assign to 'summary' because it is a read-only property.
// hello.summary = '11'

動態(tài)屬性

interface Cache {
  // 動態(tài)成員
  [prop: string]: string
}

const cache: Cache = {}

cache.foo = 'ff'

15.類

TypeScript增強了class的相關(guān)語法

  • 類的基本使用
class Person {
  // ES2017定義的語法:
  name: string // = 'init name'
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  sayHi (msg: string): void {
    console.log(`I am ${this.name}`)
  }
}
  • 訪問修飾符:private public protected 硼啤。默認是public.
export {}

class Person {
  // ES2017定義的語法:
  name: string // = 'init name'
  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}`)
  }
}

const tom = new Person('tom', 18)
console.log(tom.name)
// console.log(tom.age) // 屬性“age”為私有屬性,只能在類“Person”中訪問斧账。
// console.log(tom.gender) // 屬性“gender”受保護谴返,只能在類“Person”及其子類中訪問。

class Student extends Person {
  constructor(name: string, age: number) {
    super(name, age)
    // 父類的protected屬性子類可以訪問咧织。
    console.log(this.gender)
  }
}
  • 靜態(tài)屬性嗓袱、構(gòu)造器私有化后不能new
class Student extends Person {
  private constructor(name: string, age: number) {
    super(name, age)
    console.log(this.gender)
  }
  static create(name: string, age: number) {
    return new Student(name, age)
  }
}

const jack = Student.create('jack', 18)
  • 只讀屬性,在屬性聲明前面加上readonly即可
protected readonly gender: boolean

16.類與接口

// 盡可能讓接口簡單。一個接口只約束一個能力习绢,一個類實現(xiàn)多個接口
interface Eat {
  eat (foo: string): void
}
interface Run {
  run (distance: number): void
}
class  Person implements Eat, Run {
  eat(food: string): void {
    console.log(`優(yōu)雅的進餐:${food}`)
  }
  run(distance: number): void {
    console.log(`直立行走:${distance}`)
  }
}

class  Animal implements Eat, Run {
  eat(food: string): void {
    console.log(`呼嚕呼嚕的吃:${food}`)
  }
  run(distance: number): void {
    console.log(`爬行:${distance}`)
  }
}

17.抽象類

被abstract修飾渠抹,不能被new,只能被繼承闪萄。繼承抽象類的子類逼肯,必須實現(xiàn)父類的抽象方法

abstract class Animal {
  eat (food: string) : void {
    console.log(`呼嚕呼嚕的吃:${food}`)
  }

  // 抽象方法不需要方法體,子類必須要實現(xiàn)抽象方法
  abstract run(distance: number): void
}

// 非抽象類“Dog”不會實現(xiàn)繼承自“Animal”類的抽象成員“run”
class Dog extends Animal {
  run(distance: number): void {
    console.log(`四腳爬行:${distance}`)
  }
}

const dog = new Dog()
dog.run(20)
dog.eat('fish')

18. 泛型

把類型作為參數(shù)桃煎,放在尖括號中

function createNumberArray(length: number, value: number): number[] {
  const arr = Array<number>(length).fill(value)
  return arr
}

const res = createNumberArray(3, 100 ) // [100, 100, 100]

function createArray<T> (length: Number, value: T): T[] {
  const arr = Array<T>(length).fill(value)
}

const arrRes = createArray<string>(3, 'foo') // ['foo', 'foo', 'foo']

19. 類型聲明

TypeScript中的擴展名為d.ts的文件就是類型聲明文件

import {camelCase} from 'lodash'

// 自己寫declare語句聲明類型
declare function camelCase (input: string): string

const res = camelCase('zjal')
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篮幢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子为迈,更是在濱河造成了極大的恐慌三椿,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葫辐,死亡現(xiàn)場離奇詭異搜锰,居然都是意外死亡,警方通過查閱死者的電腦和手機耿战,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門蛋叼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人剂陡,你說我怎么就攤上這事狈涮。” “怎么了鸭栖?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵歌馍,是天一觀的道長。 經(jīng)常有香客問我晕鹊,道長松却,這世上最難降的妖魔是什么暴浦? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮晓锻,結(jié)果婚禮上歌焦,老公的妹妹穿的比我還像新娘。我一直安慰自己砚哆,他們只是感情好同规,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窟社,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绪钥。 梳的紋絲不亂的頭發(fā)上灿里,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音程腹,去河邊找鬼匣吊。 笑死,一個胖子當(dāng)著我的面吹牛寸潦,可吹牛的內(nèi)容都是我干的色鸳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼见转,長吁一口氣:“原來是場噩夢啊……” “哼命雀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起斩箫,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤吏砂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后乘客,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狐血,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年易核,在試婚紗的時候發(fā)現(xiàn)自己被綠了匈织。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡牡直,死狀恐怖缀匕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碰逸,我是刑警寧澤弦追,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站花竞,受9級特大地震影響劲件,放射性物質(zhì)發(fā)生泄漏掸哑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一零远、第九天 我趴在偏房一處隱蔽的房頂上張望苗分。 院中可真熱鬧,春花似錦牵辣、人聲如沸摔癣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽择浊。三九已至,卻和暖如春逾条,著一層夾襖步出監(jiān)牢的瞬間琢岩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工师脂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留担孔,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓吃警,卻偏偏與公主長得像糕篇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子酌心,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344