TypeScript——04——ts中的接口(Interface)

1、前言

TS新增了一個重要概念:接口,分爲對象類型接口和函數類型接口
接口能夠約束對象,函數,類的結構和類型,是一種代碼協做必須遵照的契約

接口的定義方式:後端

使用interface關鍵字

2、對象類型接口

接口中可定義 肯定屬性、可選屬性、任意屬性、只讀屬性數組

一、肯定屬性
複製代碼
interface UserInfo {
  name: string;
  age: number;
}

const myInfo: UserInfo = {
  name: "haha",
  age: 20
};
複製代碼

接口中約束好的肯定屬性,定義對象變量的時候 不能少也 不能多函數

二、可選屬性spa

複製代碼
interface UserInfo {
  name: string;
  age: number;
  sex?:string 
}

const myInfo: UserInfo = {
  name: "haha",
  age: 20
};
複製代碼

接口中的可選屬性,是表示在對象變量中能夠不存在code

三、任意屬性對象

複製代碼
interface UserInfo {
  name: string;
  age: number;
  sex?:string ;
  [propName: string]:any;
}

const myInfo: UserInfo = {
  name: "haha",
  age: 20,
  test1: 'lala',
  test2: 'ff',
  test3:123
};
複製代碼

注:一旦定義了任意屬性,那麼肯定屬性和可選屬性的類型都必須是任意屬性類型的子類;blog

定義了任意屬性後,對象變量中的屬性個數才能夠出現比接口的屬性數量多的狀況索引

四、只讀屬性接口

複製代碼
interface UserInfo {
  readonly id: number;
  name: string;
  age: number;
  sex?: string;
  [propName: string]: any;
}

const myInfo: UserInfo = {
  id: 1,
  name: "haha",
  age: 20,
  test1: "lala",
  test2: "ff",
  test3: 123
};
複製代碼

只讀屬性也是肯定屬性,在對象變量定義的時候必須有值,此後不能修改ip

對象接口示例

以查詢商品列表接口API爲例:

// 接口聲明:API協議約定返回格式
interface ResponseData {
    resCode: number;
    resData: ResultData[];
    message: string;
}

// 數據接口聲明
interface ResultData {
    productId: number;
    productName: string;
}

符合接口約定的對象:

let resultData = {
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt實戰" },
        { productId: 2, productName:"TypeScipt從入門到精通" },
    ],
    message: "success"
}

輸出函數對結果進行打印:

function render(res: ResponseData) {
    console.log(res.resCode, res.message)
    res.resData.forEach((obj) => {
        console.log(obj.productId, obj.productName)
    })
}

render(resultData);

輸出:

0 "success"
1 "TypeScipt實戰"
2 "TypeScipt從入門到精通"

額外屬性

在接口的實際調用中,後端也常常會傳遞約定以外的字段,好比:

let resultData = {
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt實戰", remark:""}, // 接口約定之外的remark字段
        { productId: 2, productName:"TypeScipt從入門到精通" },
    ],
    message: "success"
}

此時,並無報錯,TS容許這種狀況的發生

只要傳入的對象知足接口的必要條件就能夠被容許,即便傳入多餘的字段也能夠經過類型檢查

但也有例外,若是直接傳入對象字面量,TS就會對額外的字段進行類型檢查

如下方式會報錯:

render({
    resCode: 0, resData: [ { productId: 1, productName:"TypeScipt實戰", remark: "備註"}, { productId: 2, productName:"TypeScipt從入門到精通" }, ], message: "success" })

 

繞過檢查的方法有3種:

1,將對象字面量賦值給一個變量

將對象字面量賦值給一個變量後,在render再也不報錯:

let result = {
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt實戰", remark: "備註"},
        { productId: 2, productName:"TypeScipt從入門到精通" },
    ],
    message: "success"
}
render(result)
2,使用類型斷言
使用類型斷言方式,明確告訴編譯器類型是什麼,編譯器就會繞過類型檢查

方法1:

object as targetInterface
render({
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt實戰", remark:""},
        { productId: 2, productName:"TypeScipt從入門到精通" },
    ],
    message: "success"
} as ResponseData)

方法二:

<targetInterface>object
render(<ResponseData>{
    resCode: 0,
    resData: [
        { productId: 1, productName:"TypeScipt實戰", remark: "備註"},
        { productId: 2, productName:"TypeScipt從入門到精通" },
    ],
    message: "success"
})
3,使用字符串索引簽名

添加字符串索引簽名:

interface ResultData {
    productId: number;
    productName: string;
    [remark: string]: any;  // 字符串索引簽名
}
表示用任意字符串去索引List,可獲得任意結果,此時List能夠實現支持多個屬性

3、函數接口

函數定義方式

1,在TS中,可使用一個變量直接定義函數:

// 1,使用變量定義函數
let add: (x: number, y: number) => number
= (x, y){
  return x+y;
};
add(1,2)

 

2,還可使用接口來定義函數:

// 2,使用接口定義函數
interface Add {
    (x: number, y: number): number
}
let myFunc: Add = function(x, y){
  return x+y;
};
myFunc(1,2);

 

3,使用類型別名來定義函數:

類型別名使用type關鍵字,至關於爲函數類型起一個名字
// 3,使用類型別名來定義函數
type Add = (x: number, y: number) => number

 

4、可索引類型的接口

當不能肯定接口中有多少個屬性時,可使用可索引類型接口
可索引類型接口能夠用數字去索引,也能夠用字符串去索引
1,數字索引接口:

聲明一個數字索引類型的接口:

表示用任意數字去索引numberIndex都會獲得一個string
interface numberIndex {
    [x: number]: string
}
// 至關於聲明瞭一個字符串類型的數組
let chars: numberIndex = ['A', 'B']
2,字符串索引接口:

聲明一個字符串索引類型的接口:

表示用任意的字符串去索引stringIndex獲得的結果都是string
interface stringIndex {
    [x: string]: string
}

這樣聲明後,就不能聲明number類型的成員了,會報錯

interface stringIndex {
    [x: string]: string
    y: number;// Property 'y' of type 'number' is not assignable to string index type 'string'.
}
3,兩種索引簽名混用:
在上邊的字符串索引接口stringIndex中,添加數字索引簽名
interface stringIndex {
    [x: string]: string
    [z: number]: string
}
這樣作.接口既能夠用數字索引Names也能夠用字符串索引Names

但須要注意:數字索引的返回值,必定要是字符串返回類型的子類型

這是由於JS會進行類型轉換,將number轉換成string,這樣就能保證類型的兼容性

好比:將數組索引的返回值改爲number:

interface stringIndex {
    [x: string]: string
    [z: number]: number    // // Numeric index type 'number' is not assignable to string index type 'string'.
}

這樣就和String類型不兼容了,要取一個可以兼容number的類型,好比any:

interface stringIndex {
    [x: string]: any
    [z: number]: number // Numeric index type 'number' is not assignable to string index type 'string'.
}
相關文章
相關標籤/搜索