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创造的对象不是布尔值:
数值 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的区别是,undefined和null是所有类型的子类型。也就是说这两个类型的变量可以赋值给其它类型的变量,而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类型表示永远不存在的值的类型