【译】2019年开始使用Typescript
基于2018年Stack Overflow Developer的调研,TypeScript
作为编程语言比JavaScript更受“喜爱”。TypeScript在js开发者中这么受喜爱的原因是:在你运行代码前,添加到javascript中的类型有助你发现错误(代码)。TypeScript编译器提供的错误可以很好的引导你如何修复代码错误。往javascript中添加类型同时有助代码编辑器提供一些高级的功能,例如代码完成,项目范围的重构和自动模块的导入。
如果你认为TypeScript是一门全新的编程语言,那么学习它可能令人生畏。然而,TypeScript只是JavaScript的一个附加层(超集),在使用TypeScript前,你无需了解它的每个语法。TypeScript允许你通过更改文件的后缀名.js
为.ts
来轻松的转换javascript文件,并且所有的代码将作为TypeScript来正确编译。如果你想在TypeScript文件中强制执行更广的类型覆盖百分比,你可以将TypeScript配置得更具局限性,一旦你熟悉该语言了,你就可以完成此操作。
本文旨在带你快速了解一个标准的TypeScript项目中会遇到的95%的场景。剩余的5%,嗯,你可以google,还有,我会在本文底部放些有用的TypeScript资源链接。
配置TypeScript
当然,要开始编写能正确编译的TypeScript(文件),正确配置开发环境是必要的。
1、安装TypeScript编译器
首先,为了能够将TypeScript文件转换成JavaScript文件,我们需要安装TypeScript编译器。安装TypeScript可全局安装(文件系统中安装,可以在任何位置使用)或者本地安装(仅在项目级别可使用)。【个人偏向后者】
# NPM Installation Method
npm install --global typescript # Global installation
npm install --save-dev typescript # Local installation# Yarn Installation Method
yarn global add typescript # Global installation
yarn add --dev typescript # Local installation
复制代码
2、确保你的编辑器设置为支持TypeScript
你需要确保正确配置了你的编辑器以使用TypeScript。比如,为了在编辑器中能更好得使用TypeScript,你需要安装一个插件(如果你使用atom,你可以安装 atom-typescript)。如果你使用的是VS Code编辑器
,那么你不需要安装额外的插件了,因为它内置了TypeScript的支持。?
3、新建tsconfig.json文件
tsconfig.json文件是用来配置TypeScript项目设置。它应该放在项目的根目录中。该文件允许你使用不同的选项配置TypeScript编译器。
如果你仅仅是想TypeScript生效的话,你只需要tsconfig.json文件中包含一个空JSON对象,但是,如果你需要TypeScript编译器的有不同的行为(比如在特定的输出目录中输出编译后的JavaScript文件),你可以有关可以配置哪些设置的(内容)。
备注:你也可以通过运行
tsc --init
去生成一个tsconfig.json文件,其中为你设置了些默认选项,还有一些被注释掉的其他选项。
4、将TypeScript转化为JavaScript
为了将你的TypeScript代码转化成JavaScript代码,需要在控制台上跑tsc命令。运行tsc命令将告诉TypeScript编译器去搜索tsconfig.json
文件,该文件将确定项目的根目录以及编译TypeScript并将.ts
文件转换为.js
文件时用的选项。
为了快速验证设置生效,你可以创建一个测试的TypeScript文件,然后在命令行中运行tsc
,之后查看下TypeScript文件旁边是否生成了JavaScript文件。
举个例子,TypeScript文件如下...
const greeting = (person: string) => {console.log('Good day ' + person);
};
greeting('Daniel');
复制代码
应该被转换为下面这个JavaScript文件了...
var greeting = function(person) {console.log('Good day ' + person);
};
greeting('Daniel');
复制代码
如果你想TypeScript编译器(动态)监视TypeScript文件内容的变更,并自动将.ts
文件转换成.js
文件,你可以在你项目的仓库(命令行)中运行tsc -p
。
在VS Code(编辑器)中,你可以使用⌘⇧B调出一个菜单,该菜单(包含)可以在正常模式和监视模式下运行转换程序(分别对应tsc:build
和tsc:watch
)。
了解静态和动态类型
JavaScript附带7种动态类型:
- Undefined
- Null
- Boolean
- Number
- String
- Symbol
- Object
上面的类型被称为动态类型,因为它们在运行时使用。
TypeScript为JavaScript语言带来了静态类型,并且这些类型在编译时(无需运行代码)被确定。静态类型可以预测动态类型的值,这可以帮助在无需运行代码的情况下警告你可能出现的错误。
基本静态类型
好吧,我们来深入研究下TypeScript的语法。以下是TypeScript中最常见的类型。
备注:我遗漏了never和object类型,因为根据我的经验,它们并不被经常使用。
boolean
你已经很了解true
和false
值了。
let isAwesome: boolean = true;
复制代码
string
文本数据用单引号('')或双引号("")或后标记(``)【也称模版字符】包围。
let name: string = 'Chris';
let breed: string = 'Border Collie';
复制代码
如果你使用后标志,该字符串被称为模版文字,可以在里面插入表达式。
let punchline: string = 'Because it was free-range.';
let joke: string = `Q: Why did the chicken cross the road?A: ${punchline}
`;
复制代码
number
任何浮点数都给定为数字类型。作为TypeScript的一部分,支持的四种类型的数字文字是二进制,十进制,八进制和十六进制。
let decimalNumber: number = 42;
let binaryNumber: number = 0b101010; // => 42
let octalNumber: number = 0o52; // => 42
let hexadecimalNumber: number = 0x2a; // => 42
复制代码
备注:并不是只有你一个人对二进制,八进制和十六进制数字感到困惑。
array
TypeScript中有两种书写数组类型的方式。第一种是[]后缀在需要查找的数组元素类型。
let myPetFamily: string[] = ['rocket', 'fluffly', 'harry'];
复制代码
另一种可替代的方式是,Array后跟要查找的数组元素类型的Array
类型(使用尖括号包含)。
let myPetFamily: Array<string> = ['rocket', 'fluffly', 'harry'];
复制代码
tuple
元组是一个包含固定数量的元素和相关类型的数组。
let myFavoriteTuple: [string, number, boolean];
myFavoriteTuple = ['chair', 20, true]; // ✅
myFavoriteTuple = [5, 20, true]; // ❌ - The first element should be a string, not a number
复制代码
enum
枚举将名称和常量值关联,可以是数字或者字符串。当你想一组具有关联性的描述名称的不同值,枚举就很有用处了。
默认,为枚举分配从0开始的值,接下来的值为(上一个枚举值)加1。
enum Sizes {Small,Medium,Large,
}
Sizes.Small; // => 0
Sizes.Medium; // => 1
Sizes.Large; // => 2
复制代码
第一个值也可以设置为非0的值。
enum Sizes {Small = 1,Medium,Large,
}
Sizes.Small; // => 1
Sizes.Medium; // => 2
Sizes.Large; // => 3
复制代码
枚举默认是被分配数字,然而,字符串也可以被分配到一个枚举中的。
enum ThemeColors {Primary = 'primary',Secondary = 'secondary',Dark = 'dark',DarkSecondary = 'darkSecondary',
}
复制代码
any
如果变量的类型未知,并且我们并不希望类型检查器在编译时抱怨,则可以使用any
类型。
let whoKnows: any = 4; // assigned a number
whoKnows = 'a beautiful string'; // can be reassigned to a string
whoKnows = false; // can be reassigned to a boolean
复制代码
在开始使用TypeScript的时,可能会频繁使用any
类型。然而,最好尝试减少any
的使用,因为当编译器不知道与变量相关的类型时,TypeScript的有用性会降低。
void
当没有与事物相关类型的时候,void
类型应该被使用。在指定不返回任何内容的函数返回值时,最常用它。
const darkestPlaceOnEarth = (): void => {console.log('Marianas Trench');
};
复制代码
null和undefined
null和undefined都对应你在javascript中看到的null和undefined值的类型。这些类型在单独使用的时候不是很有用。
let anUndefinedVariable: undefined = undefined;
let aNullVariable: null = null;
复制代码
默认情况下,null和undefined类型是其他类型的子类型,这意味着可以为string类型的变量赋值为null或者undefined。这通常是不合理的行为,所以通常建议将tsconfig.json
文件中的strictNullChecks编译器选项设置为true。将strictNullChecks设置为true,会使null和undefined需要显示设置为变量的类型。
类型推断
幸运的是,你不需要在代码中全部位置指定类型,因为TypeScript具有类型推断。类型推断是TypeScript编译器用来自行决定类型的(内容)。
基本类型推断
TypeScript可以在变量初始化期间,设置默认参数以及确定函数返回值时推断类型。
// Variable initialization
let x = 10; // x is given the number type
复制代码
在上面的例子中,x
被分配了数字,TypeScript会以number
类型将x
变量关联起来。
// Default function parameters
const tweetLength = (message = 'A default tweet') => {return message.length;
};
复制代码
在上面的例子中,message参数被赋予了一个类型为string的默认值,因此TypeScript编译器会推断出message的类型是string,因此在访问length属性的时候并不会抛出编译错误。
function add(a: number, b: number) {return a + b;
}
const result = add(2, 4);
result.toFixed(2); // ✅
result.length; // ❌ - length is not a property of number types
复制代码
在上面这个例子中,因为TypeScript告诉add
函数,它的参数都是number
类型,那么可以推断得出返回的类型也应该是number
。
最佳通用类型推断
从多种可能的类型中推断类型时,TypeScript使用最佳通用类型算法来选择适用于所有其他候选类型的类型。
let list = [10, 22, 4, null, 5];
list.push(6); // ✅
list.push(null); // ✅
list.push('nope'); // ❌ - type 'string' is neither of type 'number' or 'null'
复制代码
在上面的例子中,数组(list)是由number
或null
类型组成的,因此TypeScript只希望number
或null
类型的值加入数组。
类型注释
当类型推断系统不够用的时,你需要在变量和对象上声明类型。
基本类型
在(上面)基本静态类型章节的介绍中,所有的类型都使用:
后跟类型名来声明。
let aBoolean: boolean = true;
let aNumber: number = 10;
let aString: string = 'woohoo';
复制代码
Arrays
在(上面)讲到的array
类型的章节中,arrays可以通过两种方式的其中一种进行注释。
// First method is using the square bracket notation
let messageArray: string[] = ['hello', 'my name is fred', 'bye'];// Second method uses the Array keyword notation
let messageArray: Array<string> = ['hello', 'my name is fred', 'bye'];
复制代码
接口
将多种类型的注释组合到一起的一种方法是使用接口。
interface Animal {kind: string;weight: number;
}
let dog: Animal;
dog = {kind: 'mammal',weight: 10,
}; // ✅
dog = {kind: true,weight: 10,
}; // ❌ - kind should be a string
复制代码
类型别名
TypeScript使用Type Alias指定多个类型注释,这事(让人)有些疑惑。【下面讲到】
type Animal = {kind: string;weight: number;
};
let dog: Animal;
dog = {kind: 'mammal',weight: 10,
}; // ✅
dog = {kind: true,weight: 10,
}; // ❌ - kind should be a string
复制代码
在使用接口或类型别名这方面,最佳的做法似乎是,在代码库保持一致情况下,通常选择接口类型或类型别名。但是,如果编写其他人可以使用的第三方的公共API,就要使用接口类型了。
如果你想了解更多关于type alias
和interface
的比较的话,我推荐你看Martin Hochel的这篇文章。
内联注释
相比创建一个可复用的接口,有时内联注释类型可能更合适。
let dog: {kind: string;weight: number;
};
dog = {kind: 'mammal',weight: 10,
}; // ✅
dog = {kind: true,weight: 10,
}; // ❌ - kind should be a string
复制代码
泛型
某些情况下,变量的特定类型无关紧要,但是应强制执行不同变量和类型之间的关系。针对这些情况,应该使用泛型类型。
const fillArray = <T>(len: number, elem: T) => {return new Array<T>(len).fill(elem);
};
const newArray = fillArray<string>(3, 'hi'); // => ['hi', 'hi', 'hi']
newArray.push('bye'); // ✅
newArray.push(true); // ❌ - only strings can be added to the array
复制代码
上面的示例中有一个泛型类型T
,它对应于传递给fillArray
函数的第二个参数类型。传递给fillArray
函数的第二个参数是一个字符串,因此创建的数组将其所有元素设置为具有字符串类型。
应该注意的是,按照惯例,单个(大写)字母用于泛型类型(比如:T
或K
)。可是,并不限制你使用更具有描述性的名称来表示你的泛型类型。下面示例就是为所提供的泛型类型使用了更具有描述性的名称:
const fillArray = <ArrayElementType>(len: number, elem: ArrayElementType) => {return new Array<ArrayElementType>(len).fill(elem);
};
const newArray = fillArray<string>(3, 'hi'); // => ['hi', 'hi', 'hi']
newArray.push('bye'); // ✅
newArray.push(true); // ❌ - only strings can be added to the array
复制代码
联合类型
在类型可以是多种类型之一的情况下,使用|
分隔符隔开不同类型的选项来使用联合类型。
// The `name` parameter can be either a string or null
const sayHappyBirthdayOnFacebook = (name: string | null) => {if (name === null) {console.log('Happy birthday!');} else {console.log(`Happy birthday ${name}!`);}
};
sayHappyBirthdayOnFacebook(null); // => "Happy birthday!"
sayHappyBirthdayOnFacebook('Jeremy'); // => "Happy birthday Jeremy!"
复制代码
交集类型
交集类型使用&
符号将多个类型组合在一起。这和(上面的)联合类型不同,因为联合类型是表示结果的类型是列出的类型之一,而交集类型则表示结果的类型是所有列出类型的集合。
type Student = {id: string;age: number;
};
type Employee = {companyId: string;
};
let person: Student & Employee;
person.age = 21; // ✅
person.companyId = 'SP302334'; // ✅
person.id = '10033402'; // ✅
person.name = 'Henry'; // ❌ - name does not exist in Student & Employee
复制代码
元组类型
元组类型使用一个:
符号,其后跟一个使用中括号包含且逗号分隔的类型列表表示。
let list: [string, string, number];
list = ['apple', 'banana', 8.75]; // ✅
list = ['apple', true, 8.75]; // ❌ - the second argument should be of type string
list = ['apple', 'banana', 10.33, 3]; // ❌ - the tuple specifies a length of 3, not 4
复制代码
可选类型
可能存在函数参数或者对象属性是可选的情况。在这些情况下,使用?
来表示这些可选值。
// Optional function parameter
function callMom(message?: string) {if (!message) {console.log('Hi mom. Love you. Bye.');} else {console.log(message);}
}
// Interface describing an object containing an optional property
interface Person {name: string;age: number;favoriteColor?: string; // This property is optional
}
复制代码
有帮助的资源
本文中未涉及到的TypeScript内容,我推荐以下的资源。
TypeScript Handbook (Official TypeScript docs)
TypeScript Deep Dive (Online TypeScript Guide)
Understanding TypeScript's Type Annotation (Great introductory TypeScript article)
原文链接 www.robertcooper.me/get-started…
文章首发 github.com/reng99/blog…
更多内容 github.com/reng99/blog…
【译】2019年开始使用Typescript相关推荐
- javascript文章_我从2019年开始的十大JavaScript文章
javascript文章 自从它作为笨拙的前端脚本语言开始以来,JavaScript已经走了很长一段路. 我们在2019年看到了JavaScript领域的一些重大发展,包括React钩子和函数式编程概 ...
- 我从2019年开始的十大JavaScript文章
JavaScript自从笨拙的前端脚本语言开始以来已经走了很长一段路. 我们在2019年看到了JavaScript领域的一些重大发展,包括React钩子和函数式编程概念的广泛采用,向TypeScrip ...
- mfc程序转化为qt_10年程序员:我都学过这些语言,2019年开始我再也不是程序员......
为什么学编程 2008年,高中毕业的我问一个已经工作两年的亲戚:什么专业工资高?他告诉我:程序员.2008年成都最低工资好像是800元,我的生活费也是800元,据他所说程序员出来的工资是2000+,于 ...
- 从2019年开始,越来越多的人关注“副业”这个词
从2019年开始,越来越多的人关注"副业"这个词,除了企业主营业务不太赚钱从而开发一些新业务以求增加利润,很多个人也悄悄地开始靠着工作之外的精力去做一切事情以增加个人收入. 然而& ...
- [译] 2019 前端性能优化年度总结 — 第五部分
原文地址:Front-End Performance Checklist 2019 - 5 原文作者:Vitaly Friedman 译文出自:掘金翻译计划 本文永久链接:github.com/xit ...
- infoq_从2019年开始的InfoQ编辑推荐讲座
infoq 重要要点 InfoQ编辑推荐的许多演示都集中在软件工程的组织和人员方面. InfoQ编辑人员享受的演示文稿提供了有关行业趋势和技术和流程发展方向的见解. 良好的会议谈话在情感上与与会者建立 ...
- [译] 2019 前端性能优化年度总结 — 第三部分
原文地址:Front-End Performance Checklist 2019 - 3 原文作者:Vitaly Friedman 译文出自:掘金翻译计划 本文永久链接:github.com/xit ...
- [译] 2019 年的 9 大设计趋势
原文地址:The 9 big design trends of 2019 原文作者:Mark Wilson 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- 译者: ...
- [译]2019年修炼前端开发者之路
原文链接The Path to Becoming a Front End Developer in 2019 一点儿我自己的铺垫 本文更多的是侧重前端入门方法,适用于那些踌躇不前无从下手的即将入门前端 ...
最新文章
- Linux下MySQL数据库的备份与还原,mysql快速导入导出数据库实例演示,解决mysql大数据量数据库导出慢的问题
- 超市账单管理系统设计思路
- 02- Image Terminology
- Windows下配置Hadoop的Java开发环境以及用Java API操作HDFS
- linux下为php添加curl扩展的方法
- 怎么确定迭代器后面还有至少两个值_为什么range不是迭代器?range到底是什么类型?
- 四大开源项目联合发布 腾讯已成Github全球贡献前十公司!
- 中台到底是什么?传统企业怎样建设中台?
- python方差的代码_Python statistics pvariance()用法及代码示例
- centos 升级 glibc和glibcxxx ,解决error: Failed dependencies等问题
- 【廖雪峰官方网站/Java教程】多线程(2)
- Codeforces Round #248 (Div. 2) B. Kuriyama Mirai's Stones
- python qq聊天机器人_Python QQBot库的QQ聊天机器人
- JavaWeb项目架构之Kafka分布式日志队列
- Java doc或docx转pdf文件预览
- html输入日期算出星座,如何通过日期计算星座
- 个人博客毕业设计设计总结
- CTS、CLS和CLR
- 在Java安装完毕之前,向导被中断
- 根据股票代码特征分类
热门文章
- 关于hkcmd.exe造成的和Eclipse之间热键冲突
- 美国只有两样东西要比中国 贵,一个是智慧财产权,一个是人工
- SWT多线程注意事项
- 使用QuickCHM软件轻松编译CHM格式的文件
- 求解最长回文子串----Manacher 算法
- css 实现一个尖角_一个讲述了 CSS 相关的技巧、动画实现 的开源项目(60篇相关文章)...
- php返回类中方法,php如何获取类中所有的方法名
- java第二章_JAVA第二章知识点
- mysql_real_connect阻塞_mysql_real_connect崩溃、未经处理的异常
- oracle 分页_80分页查询,不止写法