TypeScript
何為TypeScript
一、程式語言型別
- 動態型別語言(Dynamically Typed Language)
- 型別的檢查是在執行時才做
- 例子---JavaScript、Ruby、Python
- 靜態型別語言(Statically Typed Language)
- 型別檢查是在執行前的編譯階段
- 例子---Java、c、c++
TypeScript提前了型別檢查的時機,它是靜態弱型別語言
二、TypeScript特性
TypeScript(簡稱ts)是一種由微軟開發的自由和開源的程式語言。它是 Javascript 的一個超集,擴充套件了JavaScript的語法. 其本質上是向Javascript語言新增了可選的靜態型別和基於類的物件導向程式設計
- JavaScript that scales
- 靜態型別風格的型別系統
- 從es6到es10以至於exnext的語法支援
- 相容各種瀏覽器、系統、伺服器的開源語言
三、為什麼使用TypeScript
當使用一個語言庫的時候我們是要有這個需求的時候才用,就像一個元件的狀態管理不復雜你就沒必要用redux
和vuex
一樣,而TypeScript正是能夠解決我們開發過程中的一些痛點:
- 程式更容易理解
- 能夠知道函式或者方法輸入輸出的引數型別,外部條件
- 不用等執行的時候才能知道資料的型別
- 更容易理解別人的程式碼不用詢問
- 效率更高
- 在不同的程式碼塊和定義中進行跳轉
- 程式碼自動補全
- 更少的錯誤
- 編譯期間能發現大量錯誤
- 杜絕常見的錯誤(...undefined)
- 非常好的包容性
- 完全相容JavaScript
- 第三方庫可以直接編寫ts檔案
TypeScript的實踐
一、安裝
使用npm管理
npm install -g typescript
安裝完之後可執行tsc <檔名>.ts
命令生產.js
的檔案,在執行過程中即使因為語法不對導致編譯過程報錯,但還是會生成.js
檔案
二、資料型別
Javascript 型別分類:
① 原始資料型別 - primitive values:
- Boolean
- Null
- Undefined
- Number
- BigInt
- String
- Symbol
② Object
undefined
與null
在==
下是相等的,但在全等===
條件下是不等的,Null
型別,代表“空值”,代表一個空物件指標;Undefined
型別,當一個宣告瞭一個變數未初始化時,得到的就是undefined。
其中null
表示"沒有物件",即該處不應該有值,典型用法是:
- 作為函式的引數,表示該函式的引數不是物件
- 作為物件原型鏈的終點
而undefined
表示"缺少值",就是此處應該有一個值,但是還沒有定義。典型用法是:
- 變數被宣告瞭,但沒有賦值時,就等於undefined
- 呼叫函式時,應該提供的引數沒有提供,該引數等於undefined
- 物件沒有賦值的屬性,該屬性的值為undefined
- 函式沒有返回值時,預設返回undefined
基於Javascript的資料型別,我們在寫TypeScript的時候就會嚴格按照其型別定義資料,這樣才有便於我們程式碼的維護與規範
1、原始資料型別:
let isType: boolean = true
let count: number = 123
let userName: string = 'chenchenchen'
let u: undefined = undefined
let n: null = null
let notSure: any = 1 //可為任何型別
notSure = "rewq"
notSure = false
2、Object型別:
a、陣列:
let arrOfNumber: number[] = [1,2,3] //數字陣列
arrOfNumber.push(4)
function test() {
console.log(arguments) //類陣列
console.log(arguments.length) //長度
arguments.forEach(item => {}) //報錯
let arr: any[] = arguments //報錯,不能把類陣列賦值給陣列
}
b、元組:
let user: [string,number] = ["chen",66] //元組
const arr: (number | string)[] = [1,"2",3] //陣列
元組相比於陣列來說是明確的知道有幾個子元素也就是長度固定,而且每個子元素是什麼型別,一般元組的運用場景在匯入csv的資料格式的時候有大用
const memberList: [string,string,number][] = [
["abb","bcc",12],
["cvv","asd",24]
]
c、interface介面:
let interface Animal {
readonly id: number; //只讀不寫,與const類似
name: string;
age?: number; //該屬性不是必須
[propName: string]: any; //還可以有其他的屬性,型別是string,值是任意值
say(): string; //還可以加方法
}
let dog: Animal = {
name: "duoduo",
age: 6
}
dog.id = 9527 //報錯,只讀不寫
//interface一般可以做到型別別名的作用
interface Point {x: number, y: number} //與型別別名是一樣的效果
type Point {x: number, y: number} //型別別名
function Pythagorean(data: Point) { //型別別名,一眼看出引數的構造
return Math.sqrt(data.x **2 + data.y **2)
}
Pythagorean({ x : 4, y : 5})
型別別名和介面的區別是有的,介面只能是物件型別,而型別別名還可以是其他型別
d、Function函式
//解構寫法
function add({first , second} : {first : number; second : number}):number {
return first + second
}
const add = (x:number,y:number,z?:number):number
{ //約定輸入輸出都為數字的函式,z為可選引數
if(typeof(z) == number) {
return x+y+z
}else {
return x+y
}
}
let add2:string = add //false,函式型別不能賦值給字串型別
let add3:(x:number,y:number,z?:number) => number = add //true,一模一樣的函式型別可以賦值
function operate(): void { //不進行return的函式
console.log("sadasd")
}
介面型別還可以描述函式型別
interface Itest{
(x:number,y:number,z?:number): number
}
let add4:Itest = add //true
e、聯合型別union types
let numberorstring:number | string
numberorstring = "abc"
numberorstring = 123
型別斷言用於處理型別不確定的情況(編譯器無法判斷型別),強行讓編譯器按照你規定的型別處理
function getlength(input:string | number):number {
const str = input as string
if(str.length) {
return str.length
}else {
const number = input as number
return number.toString().length![Alt text](./docker.md)
}
}
TypeScript也提供了Type Guard
這種機制來確認具體型別
f、類Class
類(Class):定義了一切事物的抽象特點,類似於藍圖(比如汽車的一張設計圖)
物件(Object):類的例項(造出來的具體的汽車)
class Car { //定義類
color: string
constructor(color) { //在類例項化的時候才會被執行
this.color = color
}
public start() { //開放的方法
console.log(`this car is ${this.color}`)
}
}
const benz = new Car("black")
class eCar extends Car { //繼承類
run() {
console.log(`this running car is ${this.color}`)
}
}
const tesla = new eCar("white")
class aCar extends Car { //繼承類,重寫方法
static hight = "100" //靜態屬性
constructor(color) {
super(color) //子類的建構函式必須得呼叫父類的建構函式
console.log(this.color)
}
start() {
console.log(`this aCar is ${this.color}`)
}
}
const bmw = new aCar("blue")
console.log(benz.start()) //this car is black
console.log(tesla.start()) //this car is white
console.log(tesla.run()) //this running car is white
console.log(bmw.start()) //blue , this aCar is blue
console.loh(aCar.hight) //100
class Person {
constructor(private _name: string) { //定義了一個私有屬性name
}
get name() { //可以讓外部訪問私有屬性
return this._name + ' 加密'
}
set name() { //可以在外部賦值,但一般保護類的私有屬性
const realName = name.split(' ')[0] // chen
this._name = realName //私有屬性_name還是"chen"
}
}
const person = new Person("chen")
console.log(person.name); //chen 加密
person.name = 'chen 加密'
console.log(person.name) //chen 加密
一般我們通過型別註解
和型別推斷
來確認資料的型別,例如
//型別註解
let count: number;
count = 123
//型別推斷
let countInference = 123
一般當ts無法自動分析變數型別的話,我們就需要型別註解來進行標註