typescript利用接口类型声明变量_TypeScript入门指南(基础篇)
戳蓝字「前端技术优选」关注我们哦!
作者:慕晨同学
原文地址:https://github.com/USTB-musion/fee-skills/issues/19
写在前面
ts是拥有类型系统的js的超集,近年来非常火热。可以这么说,ts才是真正意义上的js。虽然ts的官方文档非常全面,但是对于原来没有接触过ts的同学来说,全篇通读下来需要耗掉不少时间,这篇文章旨在为尝试入门ts的同学使用。
本文将从以下几部分进行总结:
TypeScript的优势
强类型与弱类型的区别
动态类型与静态类型的区别
基础类型
接口类型
函数
类
泛型
TypeScript的优势
1.帮助更好地重构代码
一个好的代码习惯是常常对自己写的代码进行小的重构,使得代码可维护性更强。但是对于很多线上运行的代码,代码测试覆盖率往往不是很高,有时候哪怕一个变量名的改动,都会牵一发而动全身。而对于使用ts编写的项目就不会有这种担心。ts的静态检查特性会帮助找出代码中有错误的部分。
2.vscode等IDE的提示更加智能
js是一门动态弱类型解释语言,变量声明后可以改变类型,而且类型需要在运行时才能确定。而ts的报错提示是在编译时,不是在运行时。所以使用ts带来的静态类型检查等特性将使得IDE的提示更加完善。
3.类型声明本身就是非常好的文档
当你接手一个有历史包袱的项目时,肯定会头疼于文档和代码注释的缺失,而对于ts来说,是可以做到代码即文档的,通过声明文件可以知道哪些字段的含义以及哪些字段是必填和选填的。举个简单例子,当封装一个button的组件时:
export interface ButtonProps { style?: React.CSSProperties className?: string label?: React.ReactNode type?: 'primary' | 'default' | 'search' size?: 'sm' | 'md' | 'lg' | 'mini' disabled?: boolean title?: string onClick?: ((e: React.MouseEvent) => void)}
通过这些声明文件可以知道,当使用这个button文件时,style是一个可选值,表示一个可以自定义样式的style字段。type也是一个可选值,表示按钮的颜色类型,可以选择'primary','default','mini'其中的一种。disabled也是一个可选值,传入的值必须是boolean类型。所以就可以看出类型声明本身就是非常好的文档。
强类型与弱类型的区别
强类型语言: 强类型语言不允许改变变量的数据类型,除非进行强制类型转换。
例如:如果定义了一个字符串变量str,如果没有进行强制类型转换,是把str不能当作布尔值,整型等非字符型进行处理的。c,c++,Java等都是强类型语言。
弱类型语言: 定义与强类型语言相反,一个变量可以被赋予不同数据类型的值。
var a = '111';var b = 222;a = b;console.log(a) // 222
如以上的js代码所示,a是一个字符串变量,b是一个整型变量,但是却可以把b赋值给a,把a打印出来的值是222。
强类型的严谨性能有效地避免很多错误。
动态类型与静态类型的区别
动态类型语言: 在执行阶段才做类型检查。
例如:js/python等就是属于动态类型语言,对类型检查非常宽松,bug可能隐藏很久才被发现。
静态类型语言: 在编译阶段就做类型检查
例如: c++/Java等属于静态类型语言,对类型检查非常严格,bug在编译阶段就会被发现。能做到代码即文档。
基础类型
ES6的类型可以分为Boolean,Number,String,Array,Function,Object,Symbol,undefined,null。而TypeScript的数据类型则在ES6的基础上加上void,any,never,元组,枚举,高级类型。
基本语法
: type
TypeScript的基本类型语法是在变量之后使用冒号进行类型标识,这种语法也揭示了TypeScript的类型声明实际上是可选的。
boolean
boolean是最基础的数据类型,在ts中,使用boolean来定义布尔值
let isDone: boolean = false;
number
在ts中,使用number来定义数值类型
let num: number = 123
string
在ts中,使用string来定义字符串类型
let name: string = 'jarod'
array
在ts中,定义数组方式有两种: 一种是在可以在元素类型后面接上[],表示由此元素组成的一个数组:
let arr1: number[] = [1, 2, 3]
还有一种是使用数组泛型,Array :
let arr2: Array = [1, 2, 3]
元组
如果想在数组内表示不同元素怎么办?这时候就需要使用元组类型了。元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为number和string类型的元组。
let hello: [number, string] = [0, 'hello']
枚举
enum类型是对JavaScript标准数据类型的一个补充。像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。
enum Month { Jan, Feb, Mar}let month = [Month.Jan, Month.Feb, Month.Mar]
never
如果一个函数永远没有返回值时,我们可以声明其为void类型:
function example(): never { throw new Error('never');}
any
any是ts的一个特殊类型,一旦声明为any,则意味着关闭来ts的类型检查,
let x: any = 0;x = [];x = false;x = '';
对于any类型的变量,可以赋予任何类型的值。使用any对迁移js的项目是很友好的。但是在真正开发中,尽量还是少用any为好。
void
在ts中,void表示函数没有返回值。
function example(): void { console.log('this is void type');}
undefined和null
在TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。和 void相似,它们的本身的类型用处不是很大:
let u: undefined = undefined;let n: null = null;
readonly
一些对象属性只能在对象刚刚创建的时候修改其值。你可以在属性名前用 readonly来指定只读属性,在结合react使用的过程中的例子:
interface Props { readonly name: string;}interface State { readonly color: string;}export class Child extends React.Component { childMethod() { this.props.name = 'jarod'; // ERROR: (props are immutable) this.state.color = 'red'; // ERROR: (one should use this.setState) }}
接口类型
在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。
对象接口
赋值的时候,变量的形状必须和接口的形状保持一致。
interface Name { first: string; second: string;}
var personName:Name = { first: '张三'} // Property 'second' is missing in type '{ first: string; }' but required in type 'Name'
ts会对每一个字段做检查,如果没有对接口中声明的字段进行定义(非可选),可以看出,定义的变量比接口少一些属性则会抛出错误。
函数接口
接口能够描述JavaScript中对象拥有的各种各样的外形。除了描述带有属性的普通对象外,接口也可以描述函数类型
interface Lib { (): void; version: string; doSomething(): void;}
function getLib() { let lib = (() => {}) as Lib lib.version = '1.0.0' lib.doSomething = () => {} return lib;}
函数
函数声明
function sum(x: number, y: number) { return x + y}
函数表达式
let sum = (x: number, y: number): number => x + y
可选参数
对于参数,我们可以声明其为可选参数,即在参数后面加"?"
function buildName(firstName: string, lastName?: string) { // ...}
函数重载
重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。
function reverse(x: number): number;function reverse(x: string): string;function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); }}
类
抽象类
抽象类只能在实例中使用,不能直接被实例化。
abstract class Animal { eat() { console.log('eat') } abstract sleep(): void}
class Dog extends Animal { constructor() { super() } sleep() { console.log('Dog sleep') } // 在子类中实现父类中的抽象方法}
public, private和protected
TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public、private 和 protected。
public
public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
class Animal { public name; public constructor(name) { this.name = name; }}
let a = new Animal('Jack');console.log(a.name); // Jacka.name = 'Tom';console.log(a.name); // Tom
private
private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
class Animal { private name; public constructor(name) { this.name = name; }}
let a = new Animal('Jack');console.log(a.name); // Jacka.name = 'Tom';
// index.ts(9,13): error TS2341: Property 'name' is private and only accessible within class 'Animal'.// index.ts(10,1): error TS2341: Property 'name' is private and only accessible within class 'Animal'.
protected
protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的
class Animal { protected name; public constructor(name) { this.name = name; }}
class Cat extends Animal { constructor(name) { super(name); console.log(this.name); }}
泛型
定义:不预先确定的数据类型,具体的类型需要在使用的时候才能确定
例子:
声明一个打印函数,实现把传入的字符串打印出来:
function log(value: string): string { console.log(value) return value}
但是这时,加一个需求,要实现能把字符串数组也打印出来:
function log(value: string): stringfunction log(value: string[]): string[]function log(value: any): { console.log(value) return value}
如上所示,可以用之前的函数重载来实现。
如果这时,再加一个需求,要实现能把任何类型的参数打印出来。泛型就派上用场了:
function log(value: T): T { console.log(value); return value;}
软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
后续
Typescript实践中的进阶即将到来~
在看点这里
typescript利用接口类型声明变量_TypeScript入门指南(基础篇)相关推荐
- Kubernetes入门指南-基础篇
Kubernetes入门指南-基础篇 基础入门 kubernetes简介 kubernetes是一个平台 kubernetes架构 kubernetes不是什么 核心组件 kubernetes基本概念 ...
- TypeScript入门指南(基础篇)
写在前面 ts是拥有类型系统的js的超集,近年来非常火热.可以这么说,ts才是真正意义上的js.虽然ts的官方文档非常全面,但是对于原来没有接触过ts的同学来说,全篇通读下来需要耗掉不少时间,这篇文章 ...
- 逆向工程恶意软件入门(基础篇)
本文讲的是逆向工程恶意软件入门(基础篇), 前言 在这个系列文章中,我会向大家介绍逆向工程恶意软件的各个方面的知识.逆向工程恶意软件是一个很深奥和复杂的主题,因此很少有人掌握它,这也是这个领域的薪酬很 ...
- web快速入门之基础篇-js:3_3、简易购物车
目录 一.前言 二.js代码实例演示 1.简易购物车01_数量变化 (1)实例代码 (2)效果演示 2.简易购物车02_数量价格同步 (1)实例代码 (2)效果演示 一.前言 上一篇介绍了DHTML对 ...
- web快速入门之基础篇-html:2、基本标签之标题标签、段落标签、换行标签
目录 一.前言 二.简单实例介绍 实例代码 运行效果 三.要点说明 1.h1到h6 标题标签 2.p 段落标签 3.br 换行标签[单标记] 一.前言 上一篇文章我整理以前上学的笔记是初见 html ...
- ESP32-C3入门教程 基础篇⑪——Non-Volatile Storage (NVS) 非易失性存储参数的读写
文章目录 一.前言 二.NVS介绍 三.操作流程 3.1 读操作流程 3.2 写操作流程 四.关键函数 五.随机整数 读写示例 六.对象/数组 读写示例 七.总结 八.参考 一.前言 本文基于VS C ...
- ESP32-C3入门教程 基础篇②——GPIO口输入,按键的长按和短按
文章目录 一.前言 二.硬件准备 三.知识要点 3.1 GPIO使用 3.2 时钟节拍 四.参考例程 五.功能简述 六.源码实现 6.1 中断方式 6.2 定时扫描 七.源码详解 一.前言 本文基于V ...
- java 接口类型成员变量_18.9 接口作为成员变量类型
>[info] 接口作为成员变量类型 1.创建一个接口 ``` package cn.itcast.day11.demo07; public interface Skill { void use ...
- Spring Boot 入门之基础篇(一)
2019独角兽企业重金招聘Python工程师标准>>> 一.前言 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭 ...
最新文章
- disconf 中文乱码
- JSTL(fn函数)
- hdu 4738 2013杭州赛区网络赛 桥+重边+连通判断 ***
- 把现有的typesctipt+react项目接入到electron
- angular HttpClient post put patch del 方法(2)-Promise 服务
- 美团小程序框架mpvue入门教程
- objective-c 类目(Category)和延展(Extension)
- rabbitmq中消息的存储
- $.ajax防止多次点击重复提交的方法
- ole object interface 能获取图片吗_常见的闲鱼辅助软件有哪些,你知道吗
- Python 列表 append()函数使用详解
- 在Windows 7上安装ACE 6.1.0
- ASP.NET MVC3书店--第二节 控制器(转)
- android sdk环境配置_Mac 配置adb环境的方法
- ffmpeg java 使用教程_Java使用ffmpeg
- ZZCMS 2022版白盒审计
- Apache Airflow调度中心发布任务步骤
- 汽车软件架构学习笔记(一):九问软件架构
- 怎么阻止html渲染页面,防止浏览器假死的一个HTML5方案
- vue + vuex 实现评论和回复
热门文章
- 问题 F: 小鱼的格子裁剪(dfs)
- 阿里云IoT戴高:IoT场景化的本质是打造数智空间
- 还在犹豫吗?现在参与 OCM 社区正是时候
- 分享实录 | 单人开发场景下的测试环境实践
- 二值化_处理连续型特征:二值化与分段
- 从零点五开始用Unity做半个2D战棋小游戏(十一)
- 使用Unity引擎打造赛博朋克之城!CIGA Game Jam 2019 48小时独立游戏开发挑战
- mysql存储过程——procedure[prəˈsiːdʒər]
- Sqlserver高版本还原到低版本方法(Sqlserver2012到SqlServer2008 R2)
- SQL基础【一、SQL简介】