深入浅出TypeScript | 青训营笔记

114 阅读7分钟

在本节中主要学习TS的特点、TS的基础知识、进阶知识以及工程相关的知识

主要内容

1.为什么要学习TS

TypeScript是一门由微软推出的开源的、跨平台的编程语言。它是JavaScript的超集,扩展了 JavaScript 的语法,最终会被编译为JavaScript代码。TypeScript和JavaScript的对比如下表所示。

TypeScript的主要特性:

  • 超集 :TypeScript 是 JavaScript 的超集;
  • 类型系统:TypeScript在JavaScript的基础上,包装了类型机制,使其变身为静态类型语言;
  • 编辑器功能 :增强了编辑器和IDE功能,包括代码补全、接口提示、跳转到定义、重构等;
  • 错误提示 :可以在编译阶段就发现大部分错误,帮助调试程序。

TypeScript在JavaScript的基础上,包装了类型机制,可以进行类型检测,TypeScript就变成和Java、C++一样的类型安全的语言。这样做的好处是,能够使用可选的静态类型进行检查报错,不必像JavaScript代码在运行时才发现错误。毕竟错误发现得越早越好。TypeScript包含了编译器,支持ES新版本中的新特性,比如Babel等。虽然 TypeScript 是 JavaScript 的超集,但它始终紧跟ECMAScript标准,所以是支持ES6/7/8/9 等新语法标准的。并且,在语法层面上对一些语法进行了扩展。TypeScript 团队也正在积极的添加新功能的支持,功能未来会更加丰富,支持下一代JS。虽然 TypeScript 比较严谨,但是它并没有让 JavaScript 失去其灵活性。TypeScript 由于兼容 JavaScript 所以灵活度可以和JavaScript相媲美 , TypeScript 对类型的检查严格程度可以通过 tsconfig.json 来配置。同时TypeScript也包括了IDE功能,有完善的工具链。TypeScript是一门语言,更是生产力工具,能够进一步提升开发效率。

TypeScript 主要是为了实现以下两个目标:

  • 为JavaScript提供可选的类型系统;
  • 兼容当前以及未来的JavaScript 的特性。

TypeScript 学习教程:

2.TS基础

2.1 基础类型

数据类型关键字描述
任意类型any声明为 any 的变量可以赋予任意类型的值。
数字类型number双精度 64 位浮点值。它可以用来表示整数和分数。let binaryLiteral: number = 0b1010; // 二进制 let octalLiteral: number = 0o744; // 八进制 let decLiteral: number = 6; // 十进制 let hexLiteral: number = 0xf00d; // 十六进制
字符串类型string一个字符系列,使用单引号( ' )或双引号( " )来表示字符串类型。反引号( **** )来定义多行文本和内嵌表达式。let name: string = "Runoob"; let years: number = 5; let words: string = 您好,今年是 name发布{ name } 发布 { years + 1} 周年`;
布尔类型boolean表示逻辑值:true 和 false。let flag: boolean = true;
数组类型声明变量为数组。// 在元素类型后面加上[] let arr: number[] = [1, 2]; // 或者使用数组泛型 let arr: Array = [1, 2];
元组元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。let x: [string, number]; x = ['Runoob', 1]; // 运行正常 x = [1, 'Runoob']; // 报错 console.log(x[0]); // 输出 Runoob
枚举enum枚举类型用于定义数值集合。enum Color {Red, Green, Blue}; let c: Color = Color.Blue; console.log(c); // 输出 2
voidvoid用于标识方法返回值的类型,表示该方法没有返回值。function hello(): void { alert("Hello Runoob"); }
nullnull表示对象值缺失。
undefinedundefined用于初始化变量为一个未定义的值
nevernevernever 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

2.2 函数类型

和JavaScript不同,TypeScript在定义函数时,需要对函数的输入输出类型进行约束,在定义函数时定义输入输出的类型。例如

function sum(x: number, y: number): number {
            return x + y;
        }

另外,TypeScript中调用函数时不允许输入多余的参数或者输入比函数定义少的函数。sum(1,2,3)、sum(1)这样的做法都会报错。对于输出参数,如果省略参数的类型,typescript 会默认这个参数是 any 类型;如果省略返回值的类型,那么当函数无返回值时,typescript 默认函数返回值是 void 类型,当函数有返回值时,typescript 会根据定义的逻辑推断出返回值的类型。如下:

let mySum = function (x: number, y: number): number {
        return x + y;
    };

TypeScript在函数中要求调用函数时参数的个数和定义的参数个数一致,但对于某个函数输入参数的个数时不确定的情况,TypeScript可以通过定义可选参数的方式来解决。如下例:

function sum(x: number, y: number,z?:number) {
        if (z) {
        return x + y + z;
        } else {
        return x + y;
        }
    }

使用可选参数时,可选参数需要放在必需参数的后面,可选参数后面不能出现必需参数。

和js一样,TypeScript也可在函数中设置默认参数,如下:

function sum(x: number, y=2): number {
            return x + y;
        }

或者

function sum(x: number, y: number=2): number {
            return x + y;
        }

2.3 interface

TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

特点:

  • 可选属性 ?
  • 只读属性 readonly
  • 可以描述函数类型
  • 可以描述自定义属性

可选属性

接口的可选属性和普通函数的可选属性类似

interface Person { 
        name: string; 
        age?: number; 
    }

只读属性

用readonly来定义接口中的只读属性,只读属性仅在创建的时候被赋值,其他时候不能修改

interface Person {   
        readonly id: number;   
        name: string;  
        age?: number; 
    }

自定义属性

typescript可以在接口中定义一个自定义属性,如下面的例子:

interface Person {   
        readonly id: number;   
        name: string;  
        age?: number; 
        [hobby:string]:any
    }

最后一个属性表示满足属性名为string,属性值为any的任何数据都可以

2.4 类

typescript中的类和JavaScript中的类的写法差不多,只是增加了一些定义

特点:

  • 增加了public、private、protected修饰符
  • 抽象类:只能被继承,不能被实例化;作为基类,抽象方法必须被子类实现
  • interface约束类,使用implements关键字

3.TS进阶

3.1 高级类型

交叉类型

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

语法:T & U

其返回类型既要符合 T 类型也要符合 U 类型

联合类型

联合类型与交叉类型很有关联,但是使用上却完全不同。

语法:T | U

其返回类型为连接的多个类型中的任意一个

类型约束(extends)

语法:T extends K

这里的 extends 不是类、接口的继承,而是对于类型的判断和约束,意思是判断 T 能否赋值给 K

可以在泛型中对传入的类型进行约束。

类型映射(in)

会遍历指定接口的 key 或者是遍历联合类型

interface Person {
    name: string
    age: number
    gender: number
}


// 将 T 的所有属性转换为只读类型
type ReadOnlyType<T> = {
    readonly [P in keyof T]: T[P]
}


// type ReadOnlyPerson = {
//     readonly name: Person;
//     readonly age: Person;
//     readonly gender: Person;
// }
type ReadOnlyPerson = ReadOnlyType<Person>

3.2 泛型

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。以打印为例,想要打印出任意类型的输入,不仅仅只打印string,就需要使用到泛型:

基本使用

  • 在<>中写类型的参数,一般用T表示;
  • 使用时有两种方法指定类型:定义要使用的类型或通过TS类型推断来自动推到类型
  • 泛型的作用是临时占位,之后通过传来的类型进行推导

如下例:

4.TS实战

总结

参考链接

typescript定义函数类型

typescript学习之interface

手摸手一起学习Typescript第二天,interface接口和readonly属性

TypeScript 高级类型及用法

TS入门篇 | 为什么学习 TypeScript ?