这是我参与「第五届青训营 」笔记创作活动的第一天。
Typescript 学习背景介绍
什么是Typescript
TypeScript是JavaScript的超集,在它的基础上设计了一套新语法,提供了静态类型,高级数据类型等语言特性。但最终还是编译成JavaScript执行。
Javascript与Typescript的对比
//JavaScript
export function format(var){
let ret;
if(typeof var === 'string'){
ret = '[log]'+val;
}else{
throw new Error('param must be a string!');
}
return ret;
}
//Typescript
export function format(val:string):string{
let ret: string = ['log']+val;
return ret;
}
Typescript 基础语法讲解
Typescript 类型
泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
我们举个例子使用数组泛型来定义返回值的类型,用一个函数Array,它可以创建一个指定长度的数组,同时将每一项都填充一个默认值:
function Array<T>(length:number,value:any):Array<T>{
let result: T[] = [];
for(let i = 0;i<length;i++){
result[i] = value;
}
return result;
}
Array(4,'a'); //['a','a','a','a']
类型别名 & 类型断言
类型别名
使用type来定义类型别名,方便简化代码,方便类型复用
function sum(x:number,y:number):number {
return x+y
}
//抽取类型
type sumType = (a:number,b:number)=>number
//复用
const sum2:sumType = sum
sum2(1,2)
类型断言
有时候我们需要在还不确定类型的时候访问类型的属性和方法,但这个时候编译器往往会报错,类型断言就是告诉编译器,你比它更了解这个类型,而且他不应该因此而发生错误。
//类型断言
type inputType = string |number;
function getLength(input:inputType):number{
return (input as string).length ?(input as string).length :(input as number).toString().length
}
getLength('a')
getLength(123)
Typescript 高级类型讲解
联合类型 & 交叉类型
联合类型
联合类型表示取值可以为多种类型中的一种,使用 | 分隔每个类型。
let arr:(number |string)[] = [1,'a',3,'b']
这里的 | 在TS中叫做联合类型,即:由两个或多个其他类型组成的类型,表示可以是这些类型中的任意一种
交叉类型
交叉类型是将多个类型合并为一个类型。这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特征,使用 & 定义交叉类型。
type IntersectionType = { id: number; name: string; } & { age: number };
const mixed: IntersectionType = {
id: 1,
name: 'name',
age: 18
}
在上述实例中,我们通过交叉类型,使得IntersectionType同时拥有了id、name、age所有属性,这里我们可以试着将合并接口类型理解为求并集。
类型守卫 & 类型保护
类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。换句话说,类型保护可以保证一个字符串是一个字符串,尽管它的值也可以是一个数值。类型保护与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值。 目前主要有四种的方式来实现类型保护:
in关键字
interface Admin{
name:string;
privileges:string[];
}
interface Employee{
name:string;
startDate:Date;
}
type UnknownEmloyee = Employee | Admin;
function printEmployeeInformation(emp: UnknownEmployee){
console.log("name:"+emp.name);
if("privileges" in emp){
console.log("privileges:" + emp.prirvileges);
}
if("startDate" in emp){
console.log("Start Date:" + emp.startDate);
}
}
typeof关键字
function padLeft(value:string,padding:string | number){
if(typeof padding === "number"){
return Array(padding +1).join("") + value;
}
if(typeof padding === "string"){
return padding + value;
}
throw new Error(`Expexted string or number,got '${padding}'.`);
}
instanceof关键字
interface Padder {
getPaddingString(): string;
}
class SpaceRepeatingPadder implements Padder {
constructor(private numSpaces: number) {}
getPaddingString() {
return Array(this.numSpaces + 1).join(" ");
}
}
class StringPadder implements Padder {
constructor(private value: string) {}
getPaddingString() {
return this.value;
}
}
let padder: Padder = new SpaceRepeatingPadder(6);
if (padder instanceof SpaceRepeatingPadder) {
// padder的类型收窄为 'SpaceRepeatingPadder'
}
自定义类型保护的类型谓词
function isNumber(x: any): x is number {
return typeof x === "number";
}
function isString(x: any): x is string {
return typeof x === "string";
}
组合应用实战
Typescript 工程应用介绍
Web
- 配置webapack loader相关配置
- 配置tsconfig.js文件
- 运行webpack启动/打包
- loader处理ts文件时,会进行编译与类型检查
Node
- 安装Node与npm
- 使用npm安装tsc
- 配置tsconfig.js文件
- 使用tsc运行编译得到js文件