TypeScript

129 阅读3分钟

TypeScript 是什么

TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.
TypeScript 是一种基于JavaScript的强类型编程语言,适用于任何规模的项目。

TypeScript 特性

类型系统

类型系统按照「类型检查的时机」类分类,可以分为动态类型静态类型
动态类型 在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误;
静态类型 是指编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。
按照「是否允许隐式类型转换」来分类,可以分为强类型弱类型

TypeScript 是静态类型

let foo = 1;
foo.split(' ');
// Property 'split' does not exist on type 'number'.
// 编译时会报错(数字没有 split 方法),无法通过编译

TypeScript 强大的[类型推论],即使不去声明foo的类型,也能在变量初始化时推论出它是一个number类型。 完整的TypeScript代码是这样的:

let foo: number = 1;
foo.split(' ');
// Property 'split' does not exist on type 'number'.
// 编译时会报错(数字没有 split 方法),无法通过编译

TypeScript 是弱类型

console.log(1 + '1');
// 打印出字符串 '11'

以上这段代码不管是在 JavaScript 中还是在 TypeScript 中都是可以正常运行的,运行时数字 1 会被隐式类型转换为字符串 '1',加号 + 被识别为字符串拼接,所以打印出结果是字符串 '11'

作为对比,Python 是强类型,以下代码会在运行时报错:

print(1 + '1')
# TypeError: unsupported operand type(s) for +: 'int' and 'str'

#若要修复该错误,需要进行强制类型转换:
print(str(1) + '1')
# 打印出字符串 '11'

TypeScript在完整保留 JavaScript 运行时行为的基础上,通过引入静态类型系统来提高代码的可维护性,减少可能出现的 bug

基础

TypeScript 中的常用类型和一些基本概念

原始数据类型

JavaScript 的类型分为两种:原始数据类型和对象类型。
原始数据类型包括:布尔值、数值、字符串、null、undefined、以及ES6中的新类型 Symbol和ES10中的新类型 BigInt。

布尔值 boolean

let isDone: boolean = false;
// ES5:var isDone = false;

:使用构造函数Boolean创造的对象不是布尔值:

image.png

数值 number

let count: number = 6;
// 十进制、二进制、八进制表示法...

字符串 string

let myName: string = 'Tom';
// 模板字符串
let sentence: string = `Hello, my name is ${myName}.`;

void、null和undefined

JavaScript 没有空值(Void)的概念,在TypeScript中,可以用void表示没有任何返回值的函数:

function alertName(): void {
    alert('My name is Tom');
}

void的区别是,undefinednull是所有类型的子类型。也就是说这两个类型的变量可以赋值给其它类型的变量,而void类型的变量不能赋值给其它类型的变量:

// 这样不会报错
let num: number = undefined;
// 这样也不会报错
let u: undefined;
let num: number = u;
//下面会报错
let u: void;
let num: number = u;

其他类型

any 和 unknown

  • 任意值 any 表示允许赋值为任意类型
  • 在任意值上访问任何属性都是允许的
  • 允许调用任何方法
let myNum: any = 'seven';
myNum = 7;

let value: any;
value.foo.bar;
value.trim();
new value();
value[0][1];

如果在声明变量的时候,未指定其类型,那么它会被识别为任意值类型:

let something;
something = 'seven';
something = 7;

//等价于
let something:any;

使用 any 类型,可以很容易地编写类型正确但在运行时有问题的代码。如果我们使用 any 类型,就无法使用 TypeScript 提供的大量的保护机制。为了解决 any 带来的问题,TypeScript 3.0 引入了 unknown 类型。
所有类型也都可以赋值给unknown,这一点同any是相同的:

let value: unknown; 
value = true; // OK 
value = 42; // OK 
value = "Hello World"; // OK

其与any不同的是:

  • unknown 类型只能被赋值给 any 类型和 unknown 类型本身
  • 不允许访问属性
  • 不允许调用方法
let value: unknown; 
value.foo.bar; // Error 
value.trim(); // Error 
value(); // Error 
new value(); // Error 
value[0][1]; // Error

never

never类型表示永远不存在的值的类型