[Typescript入门 | 青训营笔记]

66 阅读4分钟

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


【Typescript入门】

Content

  • TS学习背景介绍
  • TS基础语法讲解
  • TS高级类型讲解
  • TS工程应用介绍

TS学习背景介绍

什么是TypeScript?

TS和JS相比,它们同为弱类型语言,但是不同的是,JS是动态类型语言,而TS是静态类型语言。

静态类型

  • 可读性增强:基于语法解析TSDOc,ide增强(即可以基于语法解析来自动生成文档,并且元素的类型可以代表一定的含义,增强代码的可读性)
  • 可维护性增强:在编译阶段暴露大部分错误,因而在多人合作的大型项目中,获得更好的稳定性和开发效率

TS是JS的超集:包含于兼容所有JS的特性,支持共存,支持渐进式引入与升级。

TS的基本语法

TS的基础数据类型

const q: string = 'string';
const w: number = 1;
const e: boolean = true;
const r: null = null;
const t: undefined = undefined;

对象类型

对象类型需要在名称之前加入'I'来与其他代码区分。

只读属性:约束属性不可以在对象初始化外赋值,通过关键字'readonly'

可选属性:定义该属性可以不存在 'hobby?:string;'

任意属性:约束所有对象属性都必须是该属性的子类型 '[key:string]:any'(any是TS的独有的类型,指的是可以有任意属性)

函数类型

为函数声明有两种方法:

  • 直接在函数上进行类型补充
  • 给函数变量赋值类型声明
function add(x: number, y: number): number { return x + y; } 
const mult: (x: number, y: number) => number = (x, y) => x * y;

函数也可以通过'interface'来进行声明

函数重载

可以通过接口来进行函数重载声明

在函数重载时,需要注意返回值的范围,由于TS中需要对返回值进行类型的匹配,如果说重载后返回值的类型范围不匹配要赋值的类型范围的话,那么就会报错。这种问题的解决方法就是将重载的函数的返回类型设置为any,来使得两者匹配。

数据类型

数组是一个特殊的object,数组就是一个扩展的对象,那么它的名称也需要加I.

数组的表示方法:

  • 类型+方括号
  • 泛型表示
  • 元祖表示
  • 接口表示
type IArr1 = number[];
type IArr2 = Array<string | number | Record<string, number>>;
type IArr3 = [number, number, string, string];
interface IArr4 {
  [key: number]: any;
}

TS补充类型

  • 空类型:表示无赋值
  • 任意类型:是所有类型的子类型
  • 枚举类型:支持枚举值到枚举名的正、反向映射
  • 泛型
    • 泛型约束:限制泛型必须符合字符串
    • 泛型参数默认类型(在泛型后用等号的方式来规定默认类型)
  • 类型别名和类型断言
  • 字符串/数字 字面量(允许指定字符串/数字必须的固定值)
type IEmptyFunction = () => void;
type IAnyType = any;
enum EnumExample {
    add = '+',
    mult = '*',
}
EnumExample['add'] === '+';
EnumExample['+'] === 'add';
enum ECorlor {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
ECorlor['Mon'] === 0;
ECorlor[0] === 'Mon';
type INumArr = Array<number>;

高级类型

联合/交叉类型

例如:为书籍列表编写类型,使用传统的数组类型声明繁琐,存在较多重复

改进:

  • 联合类型:IA | IB;联合类型表示一个值可以是几种类型之一
  • 交叉类型:IA & IB;多种类型叠加到一起成为一种类型,它包含了所需要的所有类型的特性

类型保护与类型守卫

类型守卫:定义一个函数,它的返回值是一个类型谓词,生效范围为子作用域。

联合类型 + 类型保护 = 自动类型推断

泛型与子集类型

在定义时对类型是不明确的,在使用的时候才对类型明确。

interface IMerge {
  <T extends Record<string, any>>(sourceObj: Partial<T>, targetObj: T): T;
}
type Ipartial<T extends Record<string, any>> = {
  [P in keyof T]?: T[P];
}
type IKeys = keyof{a: string; b: number};

函数返回值类型

函数的参数是一个函数,返回的类型是传入参数的返回类型。

关键字extends跟随泛型出现时,表示类型推断,其表达可以类比三元表达式;

关键词infer出现在类型推荐中,表示定义类型变量,可以用于指代类型。

type IDelatCall = <T extends () => any>(func: T) => ReturnType<T>;
type IReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

工程应用

Web

  • 配置webapack loader相关配置(将webapack不能识别的内容转换为可以识别的内容)
  • 配置tsconfig.js文件
  • 运行webpack启动/打包
  • loader处理ts文件时,会进行编译与类型检查

Node.Js

  • 安装Node和npm
  • 配置tsconfig.js文件
  • 使用npm安装tsc
  • 使用tsc运行编译得到js文件