TS变量与接口

变量声明

其实TS中的变量声明和JS中是一样的,所以你会JS就会TS,无外乎var、let和const,记住以下的表格内容就能解决绝大多数场景问题。

var let const
存在变量提升 不存在变量提升 不存在变量提升
不需要初始化 不需要初始化 需要初始化赋值
函数作用域 块级作用域 块级作用域
可以重复声明 不可重复声明 不可重复声明
全局作用域下,变量会成为window的属性 全局作用域下,变量不会成为window的属性 全局作用域下,变量不会成为window的属性

接口

在面向对象语言中,接口是个比较核心的概念,其作用就是对类型命名和代码定义契约,其实就是对行为的抽象,对对象的形状进行描述。在TS中就是对值所具有的结构进行类型检查。

// 原始方法
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中传入对象labelObj有string类型的label属性。而传入的对象参数实际会包含很多属性,但是编译器智慧检查那些必须的属性是否存在、类型是否匹配。printLabel2接口其实就是对printLabel中传入对象类型的抽象,定义它的参数行为,类型检查器不会关注属性的顺序。

接口对象的声明方式

接口对象的声明方式很简单,就是在接口名前加上interface即可。

interface myObj {name:string;label:string;
}

接口对象的基本属性

接口对象的属性无外乎默认属性、可选属性和只读属性等。

  • 默认属性:表示该属性必须存在,可读可改

  • 可选属性:表示该属性可有可无、可读可改,只需要在属性名后加上?符号即可,如:name?:string;。可以对可能存在的属性进行预定义,捕获引用了不存在属性时的错误。

  • 只读属性:表示该属性只能读取、不可修改,只需要在对象创建时对指定属性名前加上readonly即可,可以确保创建后不被修改。

interface LabelValue{readonly id: number;//只读属性,表示该属性只能读取、不可修改name?: string;//可选属性,表示该属性可有可无label: string;//默认属性,表示该属性必须存在
}
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;// 报错: 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}'.
// 报错: 缺少 label 属性

接口对象的函数类型

接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。

使用接口表示函数类型,需要给接口定义一个调用签名,是一个只有参数列表和返回值类型的函数,其中参数列表的每个参数都得有属性名和类型。

interface myFun{(name:string, age:number): void;//()中的是函数类型,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

我们可以看到:首先创建了一个函数类型的接口myFun,再创建了一个函数类型的变量iFun,并将同类型的函数赋值给这个变量。

对于函数类型检查而言,函数的参数名不需要与接口定义的名字匹配。类型检查器会对函数参数进行逐个检查,判断对应位置的参数类型是否匹配。当然,如果你在函数中没有指定参数类型,那么TS类型系统会根据接口进行推断,并执行检查是否匹配。

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

接口对象的可索引类型

与使用接口描述函数类型差不多,只不过可索引类型时通过描述对象索引类型和索引返回值类型的索引签名

//定义一个学生列表接口
interface StudentList{id: number;name: string;
}// 定义一个班级接口
interface ClassList{classname: string;students: StudentList[];[index: string]: any;//可以用任意的string类型去索引声明的对象, 值是any类型
}function printLabel(data:ClassList){return data;
}printLabel({classname:"class 1",numbers:30,students:[{id:2001,name:"yichuan"}]
})

可索引接口的类型只可以使用stringnumber进行定义索引签名。可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。

  • 字符串定义索引签名
  • 数字定义索引签名
  • 混合类型定义索引签名
class Animal {name: string;
}
class Dog extends Animal {breed: string;
}// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {[x: number]: Animal;[x: string]: Dog;
}

字符串索引签名能够很好的描述dictionary模式,并且它们也会确保所有属性与其返回值类型相匹配。因为字符串索引声明了obj.propertyobj["property"]两种形式都可以。

为防止给索引赋值,可以将其索引签名定义为只读类型。

interface ReadonlyStringArray {readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!

类接口

TS中可以对类设置强制执行的类型约定,即类接口。

interface FatherInterface{firstName: string;
}class Son implements FatherInterface{firstName!: String;constructor(lastName:string,age:number){};
}

注意:

  • 接口只描述类的公共部分,而不是公共和私有两部分。它不会帮你检查类是否具有某些私有成员。
  • 类实现接口时,必须实现接口所有的属性
  • 接口无法约束类的构造函数,类型检查器只会对实例部分进行检查

我们知道类具有两种类型:静态部分的类型和实例的类型。当你用构造器签名去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误:只对其实例部分进行类型检查,而constructor存在于类的静态部分,所以不在检查的范围内。

interface FatherInterface{new (firstName:string);
}class Son implements FatherInterface{constructor(firstName:string,lastName:string,age:number){};
}

继承接口

和类一样,接口也可以相互继承。可以将一个接口成员复制到另一个接口,灵活地分割接口到可复用模块中。

interface DogInterface{type:string;
}interface Erha extends DogInterface{name:string;age:number;
}let erha = <Erha>{};
erha.type = "dog";
erha.name = "bobo";
erha.age = 2;

同样的,接口也可以实现多继承。

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>{};
erha.type = "dog";
erha.name = "bobo";
erha.age = 2;
erha.foal = "分娩";

小结

interface接口的定义其实很简单,和定义对象一样的形式。接口对象的基本属性包括:默认属性、可选属性以及只读属性,其可索引类型的定义只有stringnumber两种形式,类接口进行继承的形式和类的继承大同小异。

参考文章

  • 阿宝哥的《重学TS》
  • 《ts中文文档》
  • 《大话 Typescript 接口》

写在最后

我是前端小菜鸡,感谢大家的阅读,我将继续和大家分享更多优秀的文章,此文参考了大量书籍和文章,如果有错误和纰漏,希望能给予指正。

感谢大家的阅读,我将继续和大家分享更多优秀的文章,期待大家的关注公众号【前端万有引力】。

【前端】你好,我叫TypeScript 02──变量与接口相关推荐

  1. multipartfile前端怎么传_前端那些事如何更好管理 Api 接口

    ❝ 前沿:自从前端和后端分家之后,前后端接口对接就成为了家常,"谁"也离不开谁,而对接接口的过程就离不开接口文档,比较主流就是Swagger(强大的API文档工具),当然今天它不是 ...

  2. kettle的变量空间接口VariableSpace实现与委托模式

    kettle中很多对象有变量,这些对象都实现了变量空间VariableSpace接口.这些实现类并没有都自己实现接口方法而是委托给Variables对象这个VariableSpace接口的实现类. 有 ...

  3. PTA 7-2 USB接口的定义(接口、接口变量、接口数组)

    7-2 USB接口的定义 (10 分) 定义一个USB接口,并通过Mouse和U盘类实现它,具体要求是: 1.接口名字为USB,里面包括两个抽象方法: void work():描述可以工作 void ...

  4. 前端自己导出excel表格 不需要调接口(可导出全部的数据)

    前端自己导出excel表格 不需要调接口(可导出全部的数据) 1.下载 npm install -S file-saver xlsx 2.把js放在对应的位置 全部复制(Export2Excel.js ...

  5. 让前端的子弹飞-TypeScript

    " Any application that can be written in JavaScript,will eventually be written in JavaScript. & ...

  6. 【干货分享】前端面试知识点锦集02(CSS篇)——附答案

    二.CSS部分 1.解释一下CSS的盒子模型? 回答一: a.标准的css盒子模型:宽度=内容的宽度+边框的宽度+加上内边具的宽度 b.网页设计中常听的属性名:内容(content).填充(paddi ...

  7. 前端页面生成神器以及后端变量命名神器

    1.imgcook前端页面生成具体看官网上的教程 2.后端变量命名codelf 网址 访问可能有点慢 例如:我输入一个员工,下面就会出面对应的名称 鼠标放上去会有复制的选项,非常方便

  8. 前端自学之HTML(02)

    HTML自学笔记02(接着上一篇) 超链接a 分为:文字超链接.图片超链接和导航栏 代码 <a href="网址">文字或图片</a> 连接到本站点其他网页 ...

  9. 前端上传文件保存到变量中

    需求: 用户点击上传按钮,将用户从本地上传的文件展示到页面上进行预览,没有和后端交互纯前端. 实现思路: 1.使用input标签做上传 <input ref="inputRef&quo ...

最新文章

  1. 只知道TF和PyTorch还不够,快来看看怎么从PyTorch转向自动微分神器JAX
  2. mysql-5.7.21-winx64.zip 下载安装
  3. 数据结构 - 二叉树 - 面试中常见的二叉树算法题
  4. 【redis】redisDesktopManager之redis可视化客户端 界面介绍
  5. [转载] Python字典的setdefault()方法
  6. vista下推荐大家用foobar2000播放器
  7. 2w字详解数据湖:概念、特征、架构与案例
  8. 教师节感恩_在Excel中计算感恩节日期
  9. React Native入门——布局实践:开发京东客户端首页(二)TabBar的构建
  10. HP光影精灵3 TPN-Q193显卡驱动安装不上,鲁大师检测不到显卡
  11. css文字超过两行溢出隐藏
  12. 140种Python标准库、第三方库和外部工具
  13. 大数据平台回归SQL
  14. outlook邮件搜索方法与技巧
  15. 最新前端跨平台框架推荐,跨平台开发框架选择指南
  16. Java8集合过滤操作
  17. https详解+密钥交换算法+公钥与私钥
  18. 从三驾马车到三叉戟,亚马逊云科技的中国故事
  19. U盘格式化里面的文件还能找回来吗
  20. 美团是如何基于深度学习实现图像的智能审核?

热门文章

  1. 请问大神 APACK景观分析软件怎么用啊 第一次用不会用
  2. PPT详解:自动仓储、自动分拣、自动订货系统
  3. 简单的通电延时触发电路
  4. 计算机公共基础视频教程,计算机公共基础经典教程.ppt
  5. 中国先导式电磁阀市场趋势报告、技术动态创新及市场预测
  6. mac 清除Mackeeper浏览器弹窗
  7. 2017ROS暑期学校笔记
  8. jsp驾校理论考试模拟系统ssh
  9. Red hat Linux 重启、关机、退出X、启动X 命令
  10. 哈佛图书馆的20条经典校训