TypeScript 入门 | 青训营笔记

53 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第一天。

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

  1. 配置webapack loader相关配置
  2. 配置tsconfig.js文件
  3. 运行webpack启动/打包
  4. loader处理ts文件时,会进行编译与类型检查

Node

  1. 安装Node与npm
  2. 使用npm安装tsc
  3. 配置tsconfig.js文件
  4. 使用tsc运行编译得到js文件