浅谈Vue3.0之前你必须知道的TypeScript实战技巧

很多人对TypeScript的使用还停留在基本操作上,其实TypeScript的特性非常强大,我们利用好这些特性可以有效地提高代码质量、加速开发效率,今天就介绍9个非常实用的TypeScript技巧或者特性.

注释的妙用

我们可以通过 /** */ 来注释TypeScript的类型,当我们在使用相关类型的时候就会有注释的提示,这个技巧在多人协作开发的时候十分有用,我们绝大部分情况下不用去花时间翻文档或者跳页去看注释。

巧用类型推导

TypeScript 能根据一些简单的规则推断(检查)变量的类型。

比如一个简单的add函数

function add(a: number, b: number) {
 return a + b
}

TypeScript就可以通过参数与return的运算符推导出函数的返回值

如果想获取函数整体的类型那么可以借助 typeof

注意与JavaScript中的typeof区分开

type AddFn = typeof add

当然上述情况算是比较简单的情况,有时候我们的返回值类型其实比较复杂,这个时候借助类型推导和 ReturnType 就可以很轻松地获取返回值类型。

type returnType = ReturnType<typeof add> // number

上述技巧在对redux进行编码的时候非常适用,这样可以省略我们大量的重复代码,毕竟redux的编码工作是非常繁琐的。

巧用元组

有时候我们可能需要批量的来获取参数,并且每一个参数的类型还不一样,我们可以声明一个元组如:

function query(...args:[string, number, boolean]){
 const d: string = args[0];
 const n: number = args[1];
 const b: boolean = args[2];
}

巧用Omit

有时候我们需要复用一个类型,但是又不需要此类型内的全部属性,因此需要剔除某些属性,这个时候 Omit 就派上用场了。

interface User {
 username: string
 id: number
 token: string
 avatar: string
 role: string
}
type UserWithoutToken = Omit<User, 'token'>

这个方法在React中经常用到,当父组件通过props向下传递数据的时候,通常需要复用父组件的props类型,但是又需要剔除一些无用的类型。

运用Record

Record 是TypeScript的一个高级类型,但是相关的文档并不多,所以经常被人忽略,但是是一个非常强大的高级类型。

Record允许从Union类型中创建新类型,Union类型中的值用作新类型的属性。

举个简单的例子,比如我们要实现一个简单的汽车品牌年龄表,一下写法貌似没有问题。

type Car = 'Audi' | 'BMW' | 'MercedesBenz'

const cars = {
 Audi: { age: 119 },
 BMW: { age: 113 },
 MercedesBenz: { age: 133 },
}

虽然这个写法没问题,但是有没有考虑过类型安全的问题?

比如:

  • 我们忘记写了一个汽车品牌,他会报错吗?
  • 我们拼写属性名错误了,它会报错吗?
  • 我们添加了一个非上述三个品牌的品牌进去,他会报错吗?
  • 我们更改了其中一个品牌的名字,他会有报错提醒吗?

上述这种写法统统不会,这就需要Record的帮助。

type Car = 'Audi' | 'BMW' | 'MercedesBenz'
type CarList = Record<Car, {age: number}>

const cars: CarList = {
 Audi: { age: 119 },
 BMW: { age: 113 },
 MercedesBenz: { age: 133 },
}

当我们拼写错误:

当我们少些一个品牌:

当我们添加了一个非约定好的品牌进去:

在实战项目中尽量多用Record,它会帮助你规避很多错误,在vue或者react中有很多场景选择Record是更优解。

巧用类型约束

在 .jsx 文件里,泛型可能会被当做 jsx 标签

const toArray = <T>(element: T) => [element]; // Error in .jsx file.

加 extends 可破

const toArray = <T extends {}>(element: T) => [element]; // No errors.

交叉类型

交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。

在 JavaScript 中,混入是一种非常常见的模式,在这种模式中,你可以从两个对象中创建一个新对象,新对象会拥有着两个对象所有的功能。交叉类型可以让你安全的使用此种模式:

联合类型

在 JavaScript 中,你希望属性为多种类型之一,如字符串或者数组。这就是联合类型所能派上用场的地方(它使用 | 作为标记,如 string | number)。

function formatCommandline(command: string[] | string) {
 let line = '';
 if (typeof command === 'string') {
 line = command.trim();
 } else {
 line = command.join(' ').trim();
 }
}

类型别名

类型别名会给一个类型起个新名字,类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。

类型别名可以是泛型

type Container<T> = { value: T };

也可以使用类型别名来在属性里引用自己:

type Tree<T> = {
 value: T;
 left: Tree<T>;
 right: Tree<T>;
}

类型别名看起来跟interface非常像,那么应该如何区分两者?

interface只能用于定义对象类型,而type的声明方式除了对象之外还可以定义交叉、联合、原始类型等,类型声明的方式适用范围显然更加广泛。

但是interface也有其特定的用处:

  • interface 方式可以实现接口的 extends 和 implemenjs
  • interface 可以实现接口合并声明
type Alias = { num: number }
interface Interface {
 num: number;
}
declare function aliased(arg: Alias): Alias;
declare function interfaced(arg: Interface): Interface;

此外,接口创建了一个新的名字,可以在其它任何地方使用。 类型别名并不创建新名字—比如,错误信息就不会使用别名。 在下面的示例代码里,在编译器中将鼠标悬停在interfaced上,显示它返回的是Interface,但悬停在aliased上时,显示的却是对象字面量类型。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2019-09-10

详解使用Typescript开发node.js项目(简单的环境配置)

最近在学习typescript的过程中,想到也许可以使用ts来开发node.js项目.在网上搜了一下,其实已经有很多开发者实践了这方面的内容.这里,我记录一下自己搭建开发环境的简单过程. 使用Typescript开发的好处: 较严格的类型检查和语法检查. 对ES6/ES2015/ES7(部分)支持比较好. 编译后的js文件很干净,也支持多种代码规范. 其他,请参见文档. 准备 node.js v6.9.1 或者任意的新版本,老版本暂时没有试验. tsc typescript编译器,使用npm安装

在Vue组件中使用 TypeScript的方法

注意:此文并不是把vue改为全部替换为ts,而是可以在原来的项目中植入ts文件,目前只是实践阶段,向ts转化过程中的过渡. ts有什么用? 类型检查.直接编译到原生js.引入新的语法糖 为什么用ts? TypeScript的设计目的应该是解决JavaScript的"痛点":弱类型和没有命名空间,导致很难模块化,不适合开发大型程序.另外它还提供了一些语法糖来帮助大家更方便地实践面向对象的编程. typescript不仅可以约束我们的编码习惯,还能起到注释的作用,当我们看到一函数后我们立马

详解在Vue中使用TypeScript的一些思考(实践)

Vue.extend or vue-class-component 使用 TypeScript 写 Vue 组件时,有两种推荐形式: Vue.extend():使用基础 Vue 构造器,创建一个"子类".此种写法与 Vue 单文件组件标准形式最为接近,唯一不同仅是组件选项需要被包裹在 Vue.extend() 中. vue-class-component:通常与 vue-property-decorator 一起使用,提供一系列装饰器,能让我们书写类风格的 Vue 组件. 两种形式输出

TypeScript学习之强制类型的转换

前言 使用强类型变量常常需要从一种类型向另一种类型转换,通常使用ToString或ParseInt可以来实现一些简单的转换,但是有时候需要像.NET语言中那样将一种类型显示的转换为另一种类型,在TypeScript规范中,被称为"类型断言",它仍然是类型转换,只是语法是有些不同.下面来详细看看TypeScript的强制类型转换. TypeScript强制类型转换 在 TypeScript 中将一个 number 转换成 string ,这样做会报错: var a:number = 12

js捆绑TypeScript声明文件的方法教程

前话 TypeScript是JavaScript类型的超集,这是TypeScript的文档介绍的一句话,那么他们存在联系呢? 我的理解是,TypeScript在JavaScript基础上引入强类型语言的特性.开发者使用TypeScript语法进行编程开发,最终通过转换工具将TypeScript转换成JavaScript. 使用TypeScript能够避免在原生JavaScript上开发所带来的弱类型语言的坑.(我该输入啥?调用后返回啥?哎还是看看源码吧...) 嗯!很好,强类型的JavaScri

使用TypeScript开发微信小程序的方法

TypeScript简介: TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构师,已工作于TypeScript的开发. TypeScript扩展了JavaScript的语法,所以任何现有的JavaScript程序可以不加改变的在TypeScript下工作.TypeScript是为大型应用之开发而设计,而编译时它产生 JavaScript 以确保兼容性.

详解Vue3.0 前的 TypeScript 最佳入门实践

前言 我个人对更严格类型限制没有积极的看法,毕竟各类转类型的骚写法写习惯了. 然鹅最近的一个项目中,是 TypeScript + Vue ,毛计喇,学之...-真香! 注意此篇标题的"前",本文旨在讲Ts混入框架的使用,不讲Class API 1. 使用官方脚手架构建 npm install -g @vue/cli # OR yarn global add @vue/cli 新的 Vue CLI 工具允许开发者 使用 TypeScript 集成环境 创建新项目. 只需运行 vue cr

c#程序员对TypeScript的认识过程

简介 TypeScript一直发展不错,我们公司在开发新功能时,考虑到程序的可维护性,使用了TypeScript编写浏览器上的程序,我们是从零开始使用TypeScript,甚至我连javascript也是半罐子,本文描述了一个c#程序员认识TypeScript的过程. 注:本文编写是基于Typescript0.8版本,而且初用,可能过时,具体规范可以参考http://www.typescriptlang.org 命名空间和类 作为面向对象的开发人员思维,第一个想到的是TypeScript如何定义

TypeScript 中接口详解

在 TypeScript 中,接口是用作约束作用的,在编译成 JavaScript 的时候,所有的接口都会被擦除掉,因为 JavaScript 中并没有接口这一概念. 先看看一个简单的例子: function printLabel(labelledObj: { label: string }) { console.log(labelledObj.label); } var myObj = { size: 10, label: "Size 10 Object" }; printLabel

关于TypeScript模块导入的那些事

前言 模块在其自身的作用域里执行,而不是在全局作用域里:这意味着定义在一个模块里的变量,函数,类等等在模块外部是不可见的,除非你明确地使用export之一导出它们. 相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,你必须要导入它们,可以使用import之一. 模块是自声明的.在TypeScript里,两个模块之间的关系是通过在文件级别上使用import和export建立的. 下面话不多说了,来一起看看详细的介绍吧 ES6 模块导入的限制 我们先来看一个具体的例子: 在 Node 项目

python 中的列表生成式、生成器表达式、模块导入

5.16 列表生成式 l=[] for i in range(100): l.append('egg%s' %i) print(l) ​ l=['egg%s' %i for i in range(100)] l=['egg%s' %i for i in range(1000) if i > 10] print(l) 5.17 列表生成式与生成器表达式的应用 names=['egon','alex_sb','wupeiqi','yuanhao','lxx'] res=map(lambda x:x.

python 环境变量和import模块导入方法(详解)

1.定义 模块:本质就是.py结尾的文件(逻辑上组织python代码)模块的本质就是实现一个功能 文件名就是模块名称 包: 一个有__init__.py的文件夹:用来存放模块文件 2.导入模块 import 模块名 form 模块名 import * from 模块名 import 模块名 as 新名称 3. 导入模块本质 import 模块名 ===> 将模块中所有的数据赋值给模块名,调用时需要模块名.方法名() from 模块名 import 方法名 ==>将该方法单独放到当前文件运行一遍

Python创建模块及模块导入的方法

本文实例讲述了Python创建模块及模块导入的方法.分享给大家供大家参考.具体分析如下: python学习手册中写道: 定义模块,只要使用文本编辑器,把一些python代码输入到文本中,然后以.py为后缀名进行保存,任何此类文件都会被认为是python模块. 比如说,下面的代码输入到一个文件中,就可以看作是一个模块: def printme(var): print var if __name__ == '__main__': printme(1) 假设说输入到a.py中,那么import a就可

Python中的模块导入和读取键盘输入的方法

导入模块 import 语句 想使用Python源文件,只需在另一个源文件里执行import语句,语法如下: import module1[, module2[,... moduleN] 当解释器遇到import语句,如果模块在当前的搜索路径就会被导入. 搜索路径是一个解释器会先进行搜索的所有目录的列表.如想要导入模块hello.py,需要把命令放在脚本的顶端: #!/usr/bin/python # -*- coding: UTF-8 -*- # 导入模块 import support # 现

three.js中文文档学习之通过模块导入

前言 本文主要给大家介绍了关于three.js通过模块导入的相关内容,通过 script 标签导入 three.js 是很好的入门并快速运行的方式,对于长期更新的项目有些不足,比如: 你需要手动调用和引入库里的副本,作为你项目源码的一部分. 更新库的版本是手动的过程 当引入新版本库,你的版本管理差异会与源文件混乱 使用像 NPM 这样的依赖管理能避免这些版本问题的不足. 通过 NPM 安装 three.js 已作为 npm 模块发布,详见:npm.关于npm的卸载与安装大家可以参考这篇文章:ht

对Python模块导入时全局变量__all__的作用详解

Python中一个py文件就是一个模块,"__all__"变量是一个特殊的变量,可以在py文件中,也可以在包的__init__.py中出现. 1.在普通模块中使用时,表示一个模块中允许哪些属性可以被导入到别的模块中, 如:全局变量,函数,类.如下,test1.py和main.py test1.py __all__=["test"] def test(): print('----test-----') def test1(): print('----test1----

python模块导入的细节详解

python模块导入细节 本文主要介绍了关于python模块导入的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 官方手册:https://docs.python.org/3/tutorial/modules.html 可执行文件和模块 python源代码文件按照功能可以分为两种类型: 用于执行的可执行程序文件 不用与执行,仅用于被其它python源码文件导入的模块文件 例如文件a.py和b.py在同一目录下,它们的内容分别是: # b.py x="var x in m

易语言如何导入模块?易语言模块导入的步骤

相信许多人在易语言导入模块时不知道怎么弄,接下来教大家易语言怎么导入模块 1.一.打开你的易语言,什么版本都可以的哦! 二.进入你需要加模块的易语言编程程序 三.在左边下拉栏选择程序 四.双击模块引用表 五.找到你需要添加的模块 六.双击后在这里面就有咯! 总结: 以上就是易语言进行模块导入的6个具体步骤内容,感谢大家对我们的支持.

详解JS模块导入导出

开发中基本不会将所有的业务逻辑代码放在一个JS文件中,特别是在使用前端框架,进行组件化开发中时,会复用相应的组件.这时,就会用到模块导入/导出的方法了. 当然,上面提到有模块的概念,也是在JS用于服务器端编程的时候才会出现,我们在使用前端框架时,使用npm run dev,不就是启动了一个node服务. 对于JavaScript模块化编程的起源可以追溯到2009年,Ryan Dahl在github上发布了node 的最初版本. 本文主要介绍几种模块导入/导出的方法. node 中模块导出/导入