TypeScript入門篇(一)

1、還不抓緊學習TS?

  1. TS是JS的超集,是創建在JS上的一門語言。
  2. TS可使用JS以外的擴展語法、面向對象、靜態類型。
  3. TS基礎語法 -- 爬蟲功能開發 -- TS語法進階 -- 項目接口開發 -- TS高級語法 -- 項目代碼重構 -- 項目前端開發 -- 總結

包含知識點:靜態類型、類型註解、類型推斷、泛型、類型定義文件、模塊化、打包編譯、裝飾器、Metadata(元數據)、設計模式html

2、TS基礎語法

1. TS的定義

推薦使用VSCode編輯器。由於TSVSCode都是微軟推出的。VSCode作了不少對TS的適配。前端

參考文檔:node

  1. www.tslang.cn/docs/home.h…
  2. www.typescriptlang.org/

定義:TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.TS是JS的超集,被編譯爲JS以後才能夠運行。TS是靜態代碼類型typescript

// ts文件
let a = 123
a = '123'  // 不能將類型「"123"」分配給類型「number」。由於其爲靜態類型,所以不能從number類型變爲string類型。

標準寫法
let a: number = 123
複製代碼
interface Person {
  name: string
}

const teacher: Person = {
  name: 'Fruit Bro'
}
複製代碼

2. TS的優點

參考文檔:7 個不使用 TypeScript 的理由npm

interface Point {
  x: number,
  y: number,
}
function tsDemo (data: Point) {
  return Math.sqrt(data.x ** 2 + data.y ** 2)
}

tsDemo({x: 1, y: 2})
複製代碼

優點:設計模式

  1. 開發過程當中,發現潛在問題。
  2. 更友好的編輯器自動提示。
  3. 代碼語義更清晰易懂。

3. TS基礎環境搭建

參考文檔:數組

  1. nodejs.org/
  2. nodejs.cn/

// 安裝TS
npm install typescript -g 

tsc demo.ts 就生成了demo.js文件
node demo.js // 運行生成的文件

// 轉化工具 簡化上述過程
npm install -g ts-node
// 運行
ts-node demo.ts
複製代碼

4. TS靜態類型理解

// count爲number類型以後,會具有number類型的全部屬性和方法
const count: number = 2020 

複製代碼

count.提示的都是number類型所對應的方法,以下圖: bash

// 自定義類型

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

const point: Point = {
    x: 1,
    y: 2
}
複製代碼

所以point變量具有Point全部的屬性和方法。數據結構

總結:咱們看到一個變量是靜態類型,不只僅意味着這個變量的類型不能修改,還意味這個變量的屬性和方法已基本肯定編輯器

5. TS基礎類型和對象類型

  1. 基礎類型
let count: number = 123
const personName: string = 'style'
複製代碼

還有null, undefined, symbol, boolean, void

  1. 對象類型
const teacher: {
  name: string,
  age: number,
} = {
  name: 'fruit',
  age: 18,
}
// 數組
const numbers: number[] = [1, 2, 3]

// 類
class Person {}
const fruit: Person = new Person() // fruit必須是個person類

// function, 返回值爲number的函數
const getTotal: () => number = () => {
  return 123
}
複製代碼

6. TS類型註解(type annotation)和類型推斷(type inference)

let count: number;
複製代碼

如上所示,顯式聲明變量類型的寫法,稱爲類型註解

let countInfernce = 123
const firstNumber = 1
const secondNumber = 2
const total = firstNumber + secondNumber
複製代碼

在咱們寫的代碼中,變量並無使用類型註解,但並未報錯,就是由於TS進行了類型推斷。

如上所示, 咱們並未定義變量類型,TS會自動的去嘗試分析變量的類型,稱爲類型推斷

若是TS會自動分析變量類型,咱們就什麼都不須要作了。 若是TS沒法分析變量類型的話,咱們就須要使用類型註釋。

function getTotal(firstNumber: number, secondNumber: number) {
  return firstNumber + secondNumber;
}

const total = getTotal(1, 2) // 此時就不須要寫類型註解了
複製代碼

如上所示,此時是須要些類型註解的。

7. 函數相關類型

function add(first: number, second: number): number { // 定義返回類型
  return first + second
}
const total = add(1, 2)

// 若是不定義返回類型,以下寫法不會報錯
function add(first: number, second: number) { // 未定義返回類型
  return first + second + '' // 返回字符串
}
const total = add(1, 2)
複製代碼
function sayHello (): void { // 無返回值void
  console.log('hello')
}
複製代碼
// never:這個函數永遠不會執行到最後,以下兩種狀況
function errorEmitter (): never {
  throw new Error()
  console.log('123')
}
function errorEmitter (): never {
  while(true) {}
}
複製代碼

解構賦值的類型寫法:

狀況1:
function add({ first, second }: {first: number, second: number}): number {
  return first + second
}
const total = add({first: 1, second: 2})

狀況2:
function getNumber ({first}: {first: number}) {
  return first
}
const count = getNumber({first: 1})
複製代碼

8. TS基礎語法

基礎類型 boolean、number、string、void、symbol、undefined、null

對象類型 {}、function、[]、class

上圖說明,若是聲明和賦值放在兩行寫,則沒法推斷出變量類型。所以就須要類型註解。

函數寫法1
const func = (str: string): number => {
  return parseInt(str, 10)
}
函數寫法2
const func: (str: string) => number = (str) => {
  return parseInt(str, 10)
}
複製代碼

如上圖,提示了函數的類型。
如上圖,能夠不用寫返回值,能夠用類型推斷。

如上圖,自動推斷出 Date類型。

const rawData = '{"name": "fruit"}'
const newData = JSON.parse(rawData) // JSON.parse返回的內容並不能幫助TS推斷newData的類型
複製代碼

以下圖,newData爲any

所以能夠改成以下寫法:

interface Person {
  name: string
}
const rawData = '{"name": "fruit"}'
const newData: Person = JSON.parse(rawData)
複製代碼

更多類型

let temp: number | string = 123 // temp變量有可能爲number或string
temp = '456'
複製代碼

9. TS數組和元組

元組:規定了每個元素的類型。數量個數有限的數組,同時每一項的類型又是固定的形式

數組例子

數組有兩種定義方式

方法一
let list: number[] = [1, 2, 3]
方法二
let list: Array<number> = [1, 2, 3]
複製代碼

基礎類型

// 所有爲number類型
const numberArr: number[] = [1, 2, 3]
// 爲number或string
const numberArr: (number | string)[] = [1, '2', 3]
// 所有爲string類型
const stringArr: string[] = ['a', 'b', 'c']
// 所有爲undefined類型
const undefinedArr: undefined[] = [undefined]
複製代碼

對象類型

const objectArr: {name: string, age: number}[] = [{name: 'fruit', age: 18}]
複製代碼

也能夠用類型別名

// type alias 類型別名,使用type關鍵字來定義
type User = {name: string, age: number}

const objectArr: User[] = [{name: 'fruit', age: 18}]

// 使用class
class Student {
  name: string;
  age: number;
}
const objectArr: Student[] = [
  new Student(),
  {  // 數據結構與Student保持一致也能夠
      name: 'fruit', 
      age: 18
  }
]
複製代碼

元組例子

// 元組 tuple
const teacherInfo: [string, string, number] = ['Fruit', 'male', 18];
複製代碼

元組常常用於CSVExcel等類型的文件中

// 用元組處理CSV文件
const studentList: [string, string, number][] = [
  ['fruit', 'male',   18],
  ['bro',   'female', 26],
  ['jhon',  'female', 28],
]
複製代碼

9. TS的Interface接口

interface Person {
  name: string;
}

const getPersonName = (person: Person) => {
  console.log(person.name);
};

const setPersonName = (person: Person, name: string) => {
  person.name = name;
};
複製代碼

用類型別名也能夠

type Person = {
  name: string;
}

const getPersonName = (person: Person) => {
  console.log(person.name);
};

const setPersonName = (person: Person, name: string) => {
  person.name = name;
};
複製代碼

interface接口與type類型別名的區別: type Person = string,type能夠直接表明string,但interface只能表明一個對象或函數,沒辦法表明基礎類型。規範:能用接口的儘可能用接口表示,實在無法表示再用類型別名。

interface Person {
  readonly name: string; // 只讀
  age?: number; // 可選屬性
  [propName: string]: any; // 除了name和age外,還能夠有其餘屬性,此屬性名爲字符串類型,屬性值爲任何類型
}

const getPersonName = (person: Person): void => {
  console.log(person.name);
};

const setPersonName = (person: Person, name: string): void => {
  person.name = name; // name爲只讀後,將不能賦值
};

const person = {
  name: 'fruit',
}

getPersonName(person)
setPersonName(person, 'bro')
複製代碼
第一種
const person = {
  name: 'fruit',
  sex: 'male',
}

getPersonName(person)
第二種
const person = {
  name: 'fruit',
  sex: 'male',
}

getPersonName({
  name: 'fruit',
  sex: 'male', // 此種寫法會報錯,以下圖
})
複製代碼

緣由:當以字面量的形式(第二種寫法)傳入的時候,TS會對此對象進行強校驗。以變量的形式傳入,則不會這麼嚴格(第一種寫法)。

接口中有方法

interface Person {
  name: string;
  age?: number;
  [propName: string]: any; // 除了name和age外,還能夠有其餘額外屬性,此屬性名爲字符串類型,屬性值爲任何類型
  say(): string; // 接口中有say方法,返回值爲string類型
}

const getPersonName = (person: Person): void => {
  console.log(person.name);
}

const person = {
  name: 'fruit',
  sex: 'male',
  say() { // 方法
    return 'say hello' // 返回值
  }
}

getPersonName(person)
複製代碼

interface Person {
  name: string;
  age?: number;
  [propName: string]: any;
  say(): string;
}

class User implements Person { // 類User應用Person接口

}
複製代碼

此時會報上述錯誤,由於 Person接口中 namesay方法是必傳的,類裏面必須具有接口的屬性。

下面的寫法是正確的

class User implements Person {
  name =  'fruit'
  say() {
      return 'hello fruit'
  }
}
複製代碼

接口的繼承

interface Person {
  name: string;
  age?: number;
  [propName: string]: any;
  say(): string;
}

interface Student extends Person { // Student繼承Person,並增長本身的方法study
  study(): string
}
複製代碼

函數的類型聲明定義

interface SayHi { // 函數的類型聲明
  (word: string): string // 接收string類型的參數,同時返回值爲string
}

const say: SayHi = (word: string) => {
  return word
}
複製代碼

總結:

  1. interface和type相相似,但不徹底一致。
  2. readonly 只讀屬性、?可選參數、propName 額外屬性、say()方法屬性
  3. extends 接口繼承
  4. 接口可直接定義具體的方法類型
  5. implements 用來作class類的屬性約束
  6. 接口就是在咱們開發的過程當中幫助咱們作語法提示的工具,編譯後接口和類型所有剔除掉,並不會變成js代碼

10. TS中類的定義與繼承

普通類

class Person1 {
  name = 'fruit';
  getName() {
    return this.name;
  }
}

const person2 = new Person1();
console.log(person2.getName()); // fruit
複製代碼

普通類繼承

class Teacher extends Person1 {
  getTeacherName() {
    return 'Bro';
  }
}

const teacher1 = new Teacher();
console.log(teacher1.getName()); // fruit
console.log(teacher1.getTeacherName()); // Bro
複製代碼

類的重寫

class Teacher extends Person1 {
  getTeacherName() {
    return 'Bro';
  }
  getName() { // 重寫getName
    return 'Fruit'
  }
}

const teacher1 = new Teacher();
console.log(teacher1.getName()); // Fruit
console.log(teacher1.getTeacherName()); // Bro
複製代碼

super關鍵字

class Teacher extends Person1 {
  getTeacherName() {
    return 'Bro';
  }
  getName() { // 重寫getName
    return super.getName() + 'bro' // 使用super關鍵字,調用父類的方法
  }
}

const teacher1 = new Teacher();
console.log(teacher1.getName()); // fruitbro
複製代碼

super通常用來作什麼:當一個類把父類的方法覆蓋(重寫)掉以後,此時還想調用父類的方法,此時可經過super來調用。

相關文章
相關標籤/搜索