写在前面

ts是拥有类型系统的js的超集,近年来非常火热。可以这么说,ts才是真正意义上的js。虽然ts的官方文档非常全面,但是对于原来没有接触过ts的同学来说,全篇通读下来需要耗掉不少时间,这篇文章旨在为尝试入门ts的同学使用。

本文将从以下几部分进行总结:

  1. TypeScript的优势

  2. 强类型与弱类型的区别

  3. 动态类型与静态类型的区别

  4. 基础类型

  5. 接口类型

  6. 函数

  7. 泛型

TypeScript的优势

1.帮助更好地重构代码

一个好的代码习惯是常常对自己写的代码进行小的重构,使得代码可维护性更强。但是对于很多线上运行的代码,代码测试覆盖率往往不是很高,有时候哪怕一个变量名的改动,都会牵一发而动全身。而对于使用ts编写的项目就不会有这种担心。ts的静态检查特性会帮助找出代码中有错误的部分。

2.vscode等IDE的提示更加智能

js是一门动态弱类型解释语言,变量声明后可以改变类型,而且类型需要在运行时才能确定。而ts的报错提示是在编译时,不是在运行时。所以使用ts带来的静态类型检查等特性将使得IDE的提示更加完善。

3.类型声明本身就是非常好的文档

当你接手一个有历史包袱的项目时,肯定会头疼于文档和代码注释的缺失,而对于ts来说,是可以做到代码即文档的,通过声明文件可以知道哪些字段的含义以及哪些字段是必填和选填的。举个简单例子,当封装一个button的组件时:

export interface ButtonProps {style?: React.CSSPropertiesclassName?: stringlabel?: React.ReactNodetype?: 'primary' | 'default' | 'search'size?: 'sm' | 'md' | 'lg' | 'mini'disabled?: booleantitle?: stringonClick?: ((e: React.MouseEvent<HTMLButtonElement>) => 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<number> = [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<Props,State> {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 Liblib.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); // Jack
a.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); // Jack
a.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): string
function log(value: string[]): string[]
function log(value: any): {console.log(value)return value
}

如上所示,可以用之前的函数重载来实现。

如果这时,再加一个需求,要实现能把任何类型的参数打印出来。泛型就派上用场了:

function log<T>(value: T): T {console.log(value);return value;
}

软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

TypeScript入门指南(基础篇)相关推荐

  1. Kubernetes入门指南-基础篇

    Kubernetes入门指南-基础篇 基础入门 kubernetes简介 kubernetes是一个平台 kubernetes架构 kubernetes不是什么 核心组件 kubernetes基本概念 ...

  2. typescript利用接口类型声明变量_TypeScript入门指南(基础篇)

       戳蓝字「前端技术优选」关注我们哦! 作者:慕晨同学 原文地址:https://github.com/USTB-musion/fee-skills/issues/19 写在前面 ts是拥有类型系统 ...

  3. web快速入门之基础篇-js:3_3、简易购物车

    目录 一.前言 二.js代码实例演示 1.简易购物车01_数量变化 (1)实例代码 (2)效果演示 2.简易购物车02_数量价格同步 (1)实例代码 (2)效果演示 一.前言 上一篇介绍了DHTML对 ...

  4. web快速入门之基础篇-html:2、基本标签之标题标签、段落标签、换行标签

    目录 一.前言 二.简单实例介绍 实例代码 运行效果 三.要点说明 1.h1到h6 标题标签 2.p 段落标签 3.br 换行标签[单标记] 一.前言 上一篇文章我整理以前上学的笔记是初见 html ...

  5. ClearCase指南-基础篇(连载一)

    ClearCase指南-基础篇(连载一) 第1章 前言    . 本文档凡斜体字即代表高级内容.高级概念.或可选内容,仅作粗略了解用,暂不必深入理会.   . 如下如无特别说明,缩写"CC& ...

  6. 极光小课堂 | 极光推送之 Android 客户端使用指南——基础篇

    " 本文中涉及到的所有代码现已在 Github 上开源,地址:https://github.com/xuexiangjys/JPushSample" 01 前言 - 极光推送是国内 ...

  7. 函数闭包--JavaScript权威指南--基础篇4

    函数JavaScript权威指南–基础篇4 一.知识点–函数–闭包 1.要理解函数闭包,要先知道几个概念: ①块级作用域和函数作用域的概念 FAQ:什么是块级作用域? 在类C语言中是这么定义的:变量的 ...

  8. STM32运行深度学习指南基础篇(3)(STM32CubeMX.AI+Tensorflow)

    STM32运行深度学习指南基础篇(3)(STM32CubeMX.AI+Tensorflow) 在上一篇文章中我们已经有训练好的tflite模型,接下来我们要在Clion中实现,如果是Keil的朋友可以 ...

  9. ESP32-C3入门教程 基础篇⑪——Non-Volatile Storage (NVS) 非易失性存储参数的读写

    文章目录 一.前言 二.NVS介绍 三.操作流程 3.1 读操作流程 3.2 写操作流程 四.关键函数 五.随机整数 读写示例 六.对象/数组 读写示例 七.总结 八.参考 一.前言 本文基于VS C ...

最新文章

  1. Selenium 爬虫时遇到的问题 Selenium message:session not created
  2. 模仿SDWebImage实现异步加载图片
  3. 离散周期信号的傅里叶变换
  4. html纯css页面滑动效果,纯css3滑动按钮动画效果
  5. MySQL重置root用户密码的方法【亲测可用】
  6. Android调试工具_ Stetho
  7. 马哥教育第二十二天IO模型理论、数据库基础理论、LAMP平台理论基础及mysql部署...
  8. idea重要插件代码颜色_颜色在您的网站上的重要性和品牌形象
  9. android mvc mvp 简书,浅析 MVP,MVC,MVVM模式(Android)
  10. DDR4 vs LPDDR4 vs LPDDR4x:有什么区别?
  11. 强烈推荐收藏!3W 字Python 操作 Excel 报表自动化指南
  12. Python - 学习/实践
  13. R语言的版本更新以及迁移R包
  14. 小学生都看得懂的C语言入门(1): 基础/判别/循环
  15. 金融爬虫python网贷_爬虫之爬取网贷之家在档P2P平台基本数据并存入数据库
  16. 【Matlab系列】常用模拟和数字通信系统仿真及Matlab实现
  17. qt控制程序打开记事本_基于QT记事本应用程序开发.doc
  18. Google Earth Engine APP——UI地图加载一个高程显示标签并显示高程案例
  19. Kafka 3.1的KRaft模式里的broker与controller
  20. 阿西莫夫科幻巨著 “基地三部曲”推荐

热门文章

  1. Java编程学习笔记(一)
  2. java使用groove_如何使用Groove音乐应用程序在Windows 10上添加和组织音乐
  3. 【划重点】互联网寒冬,入局必备知识点
  4. PO发布RESTful接口
  5. 手把手带你设计接口自动化测试用例(二):根据接口信息设计测试用例
  6. 如何用cmd打开python_通过cmd进入python的步骤
  7. 查看防火墙状态的命令
  8. 服务器容器配置日志(Linux+x86_64+Ubuntu18.04+CUDA11.0+python3.7)
  9. java中字符时间转成毫秒_java 时间字符串 转换 毫秒
  10. Steam无法载入网页 - 解决方案