1. 程式人生 > 實用技巧 >TypeScript の 型別定義

TypeScript の 型別定義

定義基礎型別

//字串 數字 boolean 型別
let user :string = 'Tom';
let age :number = 12;
let isShow :boolean = false

定義物件型別

// 陣列定義
let isarray1: string [] = ['boy','girl']; 
let isarray2:Array<number> = [2,1]

// 普通物件定義
let teacher:{
    name:string,
    age:number
} = {
    name:"ceshi",
    age:18
}
// 類定義
class Student{
    name:string,
    age:number
}
let xiaoming : Student = new Student();

/* 方法定義 */
// 函式表示式
let getTotal:() => number  =   () => {
    //返回值必須為number型別的方法
}

//函式宣告
function getTotal:number() {
    //返回值必須為number型別的方法
}

//解構賦值的函式
function getTotal({n1,n2} : {n1:number,n2:number}){
    
}


特殊的幾個型別

//元組型別(tuple)屬於陣列的一種,已知元素數量和型別的陣列,個元素的型別不必相同
let arrX:[string,number]
arrX = ['21',12] 

//列舉型別 enum
enum Color {Red,Green,Blue}
let mj:Color = Color.Blue
// console.log(mj)//2

enum Flag{success=1,error=2}
let s:Flag = Flag.success
// console.log(s)

// 只定義不賦值,這裡的 `any` 代表的為任意型別
let newInfo:any;  

// 多型別 -> 可以為number也可以為string
let moreName : number | string;

/*
 物件 
 name必須要有  
 但是age隨便  
 sex只讀
 say為方法,返回值必須為string
 [propName:string]: any 允許額外的引數
*/
interface moreObj{
    name: string;
    age?: number;
    readonly sex:string;
    say(): string;
    [propName:string]: any
}

定義介面並使用

//定義介面
interface Person {
    name:string,
    age:number
}

//使用介面
function sayHello(person: Person) {
    console.log(person.name + "對你說hello")
}
sayHello({name:"測試"}); //報錯的①
sayHello({name:"測試",age: 15}); //不報錯②
sayHello({name:"測試",age: 15,isBol: false});//報錯,引數型別'{name: string;age:number;isBol:boolean;}'不能賦值給型別為'Person'的引數。③

通過嘗試,上述的方法中
報錯,是因為缺少屬性age
報錯,因為這裡說不能將多一個屬性的物件賦值給一個Person

鴨子型別

let wz = {name:"測試"};
let jq = {name:"測試",age: 15};
let hq = {name:"測試",age: 15,isBol: false};
sayHello(wz);  //報錯④
sayHello(jq);  //不報錯⑤
sayHello(hq);  //不報錯⑥

按照上述的經驗,這裡的③應該會報錯,畢竟Person中沒有isBol這個屬性,但是這裡卻沒有!!!通過書本《學習JavaScript資料結構與演算法》瞭解到,TypeScript中有一種叫做鴨子概念的型別概念,大致意思就是 “看起來像鴨子,像鴨子一樣游泳,像鴨子一樣叫,那麼它一定是一直鴨子”,而這個時候hq就是看起來像鴨子,還會鴨子的叫(name),也會鴨子的游泳(age),所有這個時候③並不會報錯

思考:那麼為什麼③會報錯呢???

猜測:這裡③是直接的匿名變數,所以這裡TypeScript推斷型別的時候就會以函式的引數型別去推斷,而中的hq是帶著型別(因為在這個變數定義的時候,TypeScript就會去推斷型別,並指定上去.當然也可以事先訂好)去匹配的,最後引數的匹配型別的時候,發現這個型別裡,你要的我都有,所以就通過了,當然,這個只是我的猜想

(因為在這個變數定義的時候,TypeScript就會去推斷型別,並指定上去),並未指定具體型別,所以可以理解為鴨子型別,

let hq = {name:"測試",age: 15,isBol: false};   
=>   
//型別推斷後
let hq: {
    name:string,
    age:number,
    isBol:boolean
} = {name:"測試",age: 15,isBol: false};

//直接定義對應型別
interface newPerson {
    name:string,
    age:number,
    isBol:boolean
}
let hq:newPerson = {name:"測試",age: 15,isBol: false};

這裡可以看到,型別檢測不只是可以幫我們看到檢測資料的型別,還為我們提供相應型別的方法,也提供了介面內部屬性的一個提示,為我們的開發提供效率以及準確性


已經定義的型別不能改變,

let wang = {name:"wangwu",age:54}
wang.name = 55;

當型別聲明後就不能隨意改變其型別,這樣程式碼更易維護與閱讀

最後想說

以上說的報錯,並不是執行時的報錯,而是編碼是的報錯提示,這樣有效的使程式碼上線後出現bug的概率下降