新聞中心
TS變量與接口
變量聲明
其實(shí)TS中的變量聲明和JS中是一樣的,所以你會(huì)JS就會(huì)TS,無外乎var、let和const,記住以下的表格內(nèi)容就能解決絕大多數(shù)場景問題。

接口在面向?qū)ο笳Z言中,接口是個(gè)比較核心的概念,其作用就是對(duì)類型命名和代碼定義契約,其實(shí)就是對(duì)行為的抽象,對(duì)對(duì)象的形狀進(jìn)行描述。在TS中就是對(duì)值所具有的結(jié)構(gòu)進(jìn)行類型檢查。
- // 原始方法
- function printLabel(labelObj: {label:string}){
- console.log(labelObj.label);
- }
- let myObj = {name:"wenbo",label:"size 110"};
- printLabel(myObj);
- // 接口方法
- interface LabelValue {
- label: string;
- }
- function printLabel2(labelValue:LabelValue){
- console.log(labelValue.label);
- }
- printLabel2(myObj);
上述代碼表明,printLabel中傳入對(duì)象labelObj有string類型的label屬性。而傳入的對(duì)象參數(shù)實(shí)際會(huì)包含很多屬性,但是編譯器智慧檢查那些必須的屬性是否存在、類型是否匹配。printLabel2接口其實(shí)就是對(duì)printLabel中傳入對(duì)象類型的抽象,定義它的參數(shù)行為,類型檢查器不會(huì)關(guān)注屬性的順序。
接口對(duì)象的聲明方式
接口對(duì)象的聲明方式很簡單,就是在接口名前加上interface即可。
- interface myObj {
- name:string;
- label:string;
- }
接口對(duì)象的基本屬性
接口對(duì)象的屬性無外乎默認(rèn)屬性、可選屬性和只讀屬性等。
- 默認(rèn)屬性:表示該屬性必須存在,可讀可改
- 可選屬性:表示該屬性可有可無、可讀可改,只需要在屬性名后加上?符號(hào)即可,如:name?:string;??梢詫?duì)可能存在的屬性進(jìn)行預(yù)定義,捕獲引用了不存在屬性時(shí)的錯(cuò)誤。
- 只讀屬性:表示該屬性只能讀取、不可修改,只需要在對(duì)象創(chuàng)建時(shí)對(duì)指定屬性名前加上readonly即可,可以確保創(chuàng)建后不被修改。
- interface LabelValue{
- readonly id: number;//只讀屬性,表示該屬性只能讀取、不可修改
- name?: string;//可選屬性,表示該屬性可有可無
- label: string;//默認(rèn)屬性,表示該屬性必須存在
- }
- function printLabel(labelValue:LabelValue){
- console.log(labelValue);
- }
- let myObj: LabelValue = {name:"yichuan",id:100,label:"size 110"};
- printLabel(myObj);//{ name: 'yichuan', id: 100, label: 'size 110' }
- myObj.id = 200;// 報(bào)錯(cuò): Cannot assign to 'id' because it is a constant or a read-only property.
- let myObj2: LabelValue ={id:100};
- // Type '{ id: number}' is not assignable to type 'LabelValue'.
- // Property 'label' is missing in type '{ id: number}'.
- // 報(bào)錯(cuò): 缺少 label 屬性
接口對(duì)象的函數(shù)類型
接口能夠描述JavaScript中對(duì)象擁有的各種各樣的外形。 除了描述帶有屬性的普通對(duì)象外,接口也可以描述函數(shù)類型。
使用接口表示函數(shù)類型,需要給接口定義一個(gè)調(diào)用簽名,是一個(gè)只有參數(shù)列表和返回值類型的函數(shù),其中參數(shù)列表的每個(gè)參數(shù)都得有屬性名和類型。
- interface myFun{
- (name:string, age:number): void;//()中的是函數(shù)類型,void是否有返回值
- }
- let iFun: myFun;
- iFun = function (name:string,age:number){
- console.log(`my name is ${name}, my age is ${age}`)
- }
- iFun("yichuan",18);//my name is yichuan, my age is 18
我們可以看到:首先創(chuàng)建了一個(gè)函數(shù)類型的接口myFun,再創(chuàng)建了一個(gè)函數(shù)類型的變量iFun,并將同類型的函數(shù)賦值給這個(gè)變量。
對(duì)于函數(shù)類型檢查而言,函數(shù)的參數(shù)名不需要與接口定義的名字匹配。類型檢查器會(huì)對(duì)函數(shù)參數(shù)進(jìn)行逐個(gè)檢查,判斷對(duì)應(yīng)位置的參數(shù)類型是否匹配。當(dāng)然,如果你在函數(shù)中沒有指定參數(shù)類型,那么TS類型系統(tǒng)會(huì)根據(jù)接口進(jìn)行推斷,并執(zhí)行檢查是否匹配。
- interface myFun{
- (name:string, age:number): void;
- }
- let iFun: myFun;
- iFun = function (name,age){
- console.log(`my name is ${name}, my age is ${age}`)
- }
- iFun("yichuan",18);////my name is yichuan, my age is 18
接口對(duì)象的可索引類型
與使用接口描述函數(shù)類型差不多,只不過可索引類型時(shí)通過描述對(duì)象索引類型和索引返回值類型的「索引簽名」。
- //定義一個(gè)學(xué)生列表接口
- interface StudentList{
- id: number;
- name: string;
- }
- // 定義一個(gè)班級(jí)接口
- interface ClassList{
- classname: string;
- students: StudentList[];
- [index: string]: any;//可以用任意的string類型去索引聲明的對(duì)象, 值是any類型
- }
- function printLabel(data:ClassList){
- return data;
- }
- printLabel({
- classname:"class 1",
- numbers:30,
- students:[{
- id:2001,
- name:"yichuan"
- }]
- })
可索引接口的類型只可以使用string和number進(jìn)行定義索引簽名??梢酝瑫r(shí)使用兩種類型的索引,但是數(shù)字索引的返回值必須是字符串索引返回值類型的子類型。當(dāng)使用 number來索引時(shí),JavaScript會(huì)將它轉(zhuǎn)換成string然后再去索引對(duì)象。
- 字符串定義索引簽名
- 數(shù)字定義索引簽名
- 混合類型定義索引簽名
- class Animal {
- name: string;
- }
- class Dog extends Animal {
- breed: string;
- }
- // 錯(cuò)誤:使用數(shù)值型的字符串索引,有時(shí)會(huì)得到完全不同的Animal!
- interface NotOkay {
- [x: number]: Animal;
- [x: string]: Dog;
- }
字符串索引簽名能夠很好的描述dictionary模式,并且它們也會(huì)確保所有屬性與其返回值類型相匹配。因?yàn)樽址饕暶髁薿bj.property和obj["property"]兩種形式都可以。
為防止給索引賦值,可以將其索引簽名定義為只讀類型。
- interface ReadonlyStringArray {
- readonly [index: number]: string;
- }
- let myArray: ReadonlyStringArray = ["Alice", "Bob"];
- myArray[2] = "Mallory"; // error!
類接口
TS中可以對(duì)類設(shè)置強(qiáng)制執(zhí)行的類型約定,即類接口。
- interface FatherInterface{
- firstName: string;
- }
- class Son implements FatherInterface{
- firstName!: String;
- constructor(lastName:string,age:number){};
- }
注意:
- 接口只描述類的公共部分,而不是公共和私有兩部分。它不會(huì)幫你檢查類是否具有某些私有成員。
- 類實(shí)現(xiàn)接口時(shí),必須實(shí)現(xiàn)接口所有的屬性
- 接口無法約束類的構(gòu)造函數(shù),類型檢查器只會(huì)對(duì)實(shí)例部分進(jìn)行檢查
我們知道類具有兩種類型:靜態(tài)部分的類型和實(shí)例的類型。當(dāng)你用構(gòu)造器簽名去定義一個(gè)接口并試圖定義一個(gè)類去實(shí)現(xiàn)這個(gè)接口時(shí)會(huì)得到一個(gè)錯(cuò)誤:只對(duì)其實(shí)例部分進(jìn)行類型檢查,而constructor存在于類的靜態(tài)部分,所以不在檢查的范圍內(nèi)。
- interface FatherInterface{
- new (firstName:string);
- }
- class Son implements FatherInterface{
- constructor(firstName:string,lastName:string,age:number){};
- }
繼承接口
和類一樣,接口也可以相互繼承。可以將一個(gè)接口成員復(fù)制到另一個(gè)接口,靈活地分割接口到可復(fù)用模塊中。
- interface DogInterface{
- type:string;
- }
- interface Erha extends DogInterface{
- name:string;
- age:number;
- }
- let erha =
{}; - erha.type = "dog";
- erha.name = "bobo";
- erha.age = 2;
同樣的,接口也可以實(shí)現(xiàn)多繼承。
- class Son implements FatherInterface{
- constructor(firstName:string,lastName:string,age:number){};
- }
- interface AnimalInterface{
- foal:string;
- }
- interface DogInterface{
- type:string;
- }
- interface Erha extends DogInterface, AnimalInterface{
- name:string;
- age:number;
- }
- let erha =
{}; - erha.type = "dog";
- erha.name = "bobo";
- erha.age = 2;
- erha.foal = "分娩";
小結(jié)
interface接口的定義其實(shí)很簡單,和定義對(duì)象一樣的形式。接口對(duì)象的基本屬性包括:默認(rèn)屬性、可選屬性以及只讀屬性,其可索引類型的定義只有string和number兩種形式,類接口進(jìn)行繼承的形式和類的繼承大同小異。
參考文章
- 阿寶哥的《重學(xué)TS》
- 《ts中文文檔》
- 《大話 Typescript 接口》
本文轉(zhuǎn)載自微信公眾號(hào)「前端萬有引力」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系前端萬有引力公眾號(hào)。
網(wǎng)站欄目:【前端】你好,我叫TypeScript 02──變量和接口
網(wǎng)頁地址:http://www.fisionsoft.com.cn/article/djheheg.html


咨詢
建站咨詢
