基本类型和拓展类型
Typescript 与 JavaScript 共享基本类型,拓展了一些类型
- 元组 Tuple
- 枚举 Enum
- any和void
- 从不类型 never
共有基本类型
1 |
|
object 类型,统指非number, string, null, undefined, boolean等基本类型的复杂类型
1 |
|
元组 Tuple
元组类型允许你用固定数量的元素表示数组,这些元素的类型是已知的,但不必相同
1 |
|
enum 枚举
enum类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。
1 | // 默认情况从0开始为元素编号,也可手动为1开始 |
枚举的应用场景适合定义一些固定的状态,比如应用得状态
1 |
|
any和void、从不类型never
- any 用于不确定值得类型情况下,给变量定义any类型,但是不能多用,不然用ts就失去意义了
- void表示空值返回,比如
1
2
3declare function test(): void{
console.log("啥都没有返回")
} - never表示永远也到不了的情况,也叫从不类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function error(message: string): never {
throw new Error(message);
}
function fail() {
return error("Something failed");
}
// 函数返回绝不能具有无法到达的终点
function infiniteLoop(): never {
while (true) {
}
}
类型断言
简略的定义是:可以用来手动指定一个值的类型。
有两种写法,尖括号和as:
1 | let bar: any = "str"; |
泛型 Generics
先来看一个demo
1 | function demo(arg: number): number { |
demo这个函数直接返回了传入的值,这个时候确定的是number类型,所以也直接返回了number类型
软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用。支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性。
在C#和Java中,可以使用”泛型”来创建可复用的组件,并且组件可支持多种数据类型。这样便可以让用户根据自己的数据类型来使用组件。
泛型方法
在ts里,声明泛型方法
1 | function identity<T>(arg: T): T { |
调用泛型方法
1 | identity<string>("112121"); |
泛型与any
typescript的特殊类型any在使用的时候可以代替任意的类型,看似和泛型很像,但实际上有很大差别
1 | function anyDemo(arg: any):any { |
- anyDemo, 因为arg的类型是any,所以可以打印length属性,但是如果arg的实际输入类型不是带有length属性的变量,会抛出异常
- genericsDemo, 定义了arg类型是数组的泛型类型,所以一定有length属性,所以不会抛出异常
自定义类型类型
interface 与 type的区别
相同点
都可以描述一个对象或函数
1 | // interface |
拓展(extends)与 交叉类型(Intersection Types)
interface是可以extends,但是type是不允许extends和implement的。但是type却可以通过交叉类型实现interface 的extends行为,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 与 interface 类型 交叉 。
虽然效果差不多,但是两者语法不同。
1 | // interface extends interface |
不同点
type 可以而 interface 不行
- type 可以声明基本类型别名,联合类型,元组等类型
1 | // 基本类型别名 |
- type 语句中还可以使用 typeof 获取实例的 类型进行赋值
1 |
|
- 其他骚操作
1 |
|
interface 可以而 type 不行
1 | // interface 能够声明合并 |
实现与继承: implements 和 extends
extends 很明显就是ES6里面的类继承,那么implements 又是做什么的?他和extends有什么不同?
implements 实现。与C#或Java里接口的基本作用一样,TypeScript也能够用它来明确的强制一个类去符合某种契约
implements 基本方法:
1 | interface Bar { |
而, extends 是继承父类,两者其实可以混用:
1 |
|
声明文件与命名空间: declare 和 namespace
比如Vue项目中的 shims-tsx.d.ts 和 shims-vue.d.ts ,其初始内容是这样的:
1 |
|
declare: 当使用第三方库时,我们需要引用他的声明文件,才能获得对应的代码补全,接口提示等功能。
1 |
|
namespace:“内部模块”现在称做“命名空间”
module X { 相当于现在推荐的写法 namespace X {)
Typescript3.7已发布,新特性有些哪些?
Optional chaining (可选链)
1 |
|
Nullish Coalescing (空值合并)
空值合并运算符是 || 的替代方法, 如果左边是 null 或 undefined 就返回右边;
看一个例子:
1 |
|
等等…