这是我参与11月更文挑战的第 1 天,活动详情查看:2021最后一次更文挑战
前言
TypeScript 由微软开发的,是 JavaScript 的一个超集,扩展了 JavaScript 的语法。
TypeScript 通过类型注解提供编译时的静态类型检查,可以通过tsc命令编译成 JavaScript。
TypeScript 区分大小写。
TypeScript 支持两种类型的注释:
// 这是一个单行注释
/*
这是一个多行注释
这是一个多行注释
这是一个多行注释
*/
tsc
安装 typescript
npm install -g typescript
之后,可以使用 tsc 命令来执行 TypeScript 的相关代码。
tsc常用命令
查看tsc支持的命令有哪些:
tsc --help
常用命令有:
-h, --help 查看帮助
-v, --version 输出tsc的版本号
-d, --declaration 生成对应的'.d.ts'文件
--init 初始化项目并生成tsconfig.json文件
--sourceMap 生成对应的'.map'文件
--outFile FILE 定义输出文件
--outDir DIRECTORY 重定向输出文件夹
--removeComments 删除文件的注释
-w, --watch 会监听输入的文件,在发生改变时重新编译。
如:
tsc -v
// Version 4.0.3
tsc app.ts -w
// ...
编译app.ts文件
app.ts内容为:
var message:string = "Hello World"
console.log(message)
编译该文件
tsc app.ts
生成了app.js文件,内容为:
var message = "Hello World";
console.log(message);
同时编译多个 ts 文件
tsc file1.ts file2.ts file3.ts
TypeScript 编译过程
TypeScript 转换为 JavaScript 过程如下图所示:
ts-node
ts-node is a TypeScript execution engine and REPL for Node.js.
ts-node是TypeScript执行引擎和Node.js的REPL(Read-Evaluate-Print-Loop, 交互式解释器)。
常用命令:
# Execute a script as `node` + `tsc`.
ts-node script.ts
# Execute code with TypeScript.
ts-node -e 'console.log("Hello, world!")'
# Execute, and print, code with TypeScript.
ts-node -p -e '"Hello, world!"'
# Pipe scripts to execute with TypeScript.
echo 'console.log("Hello, world!")' | ts-node
# Equivalent to ts-node --transpile-only
ts-node-transpile-only script.ts
# Equivalent to ts-node --cwd-mode
ts-node-cwd script.ts
# Starts a TypeScript REPL.
ts-node
REPL实例
$ ts-node
> let a = "hh"
> a
'hh'
let b:number = "hh"
// error TS2322: Type 'string' is not assignable to type 'number'.
> let c:number = 11
> c
11
基础类型
any
可以为还不清楚类型的变量指定一个类型。
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
number
和JavaScript一样,TypeScript里的所有数字都是浮点数。 这些浮点数的类型是 number。 除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;
string
let name: string = "Tom";
boolean
let isDone: boolean = false;
数组
// 在元素类型后面加上[]
let arr: number[] = [1, 2];
// 或者使用数组泛型
let arr: Array<number> = [1, 2];
// 定义存储各种类型数据的数组时,示例代码如下:
let arrayList: any[] = [1, false, 'fine'];
arrayList[1] = 100;
元组
元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。
let x: [string, number];
x = ['hhh', 1]; // 运行正常
x = [1, 'hhh']; // 报错
console.log(x[0]); // 输出 hhh
枚举
枚举类型用于定义数值集合。
enum Color {Red, Green, Blue};
let c: Color = Color.Blue;
console.log(c); // 输出 2
void
某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:
function warnUser(): void {
console.log("This is my warning message");
}
null, undefined
undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大:
// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;
默认情况下null和undefined是所有类型的子类型。 就是说你可以把 null和undefined赋值给number类型的变量。
然而,当你指定了--strictNullChecks标记,null和undefined只能赋值给void和它们各自。 这能避免 很多常见的问题。 也许在某处你想传入一个 string或null或undefined,你可以使用联合类型string | null | undefined。
never
never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。
// 启用 --strictNullChecks
let x: number | null | undefined;
x = 1; // 运行正确
x = undefined; // 运行正确
x = null; // 运行正确
声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环),示例代码如下:
let x: never;
let y: number;
// 运行错误,数字类型不能转为 never 类型
x = 123;
// 运行正确,never 类型可以赋值给 never类型
x = (()=>{ throw new Error('exception')})();
// 运行正确,never 类型可以赋值给 数字类型
y = (()=>{ throw new Error('exception')})();
// 返回值为 never 的函数可以是抛出异常的情况
function error(message: string): never {
throw new Error(message);
}
// 返回值为 never 的函数可以是无法被执行到的终止点的情况
function loop(): never {
while (true) {}
}
object
object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。
使用object类型,就可以更好的表示像Object.create这样的API。例如:
declare function create(o: object | null): void;
create({ prop: 0 }); // OK
create(null); // OK
create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error
类型断言(Type Assertion)
类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。
类型断言有两种形式。 其一是“尖括号”语法:
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
另一个为as语法:
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
两种形式是等价的。
当你在TypeScript里使用JSX时,只有 as语法断言是被允许的。
类型推断(Type Inference)
TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型。
let x = 3;
变量x的类型被推断为数字。 这种推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时。
如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型。
var num = 2; // 类型推断为 number
console.log("num 变量的值为 "+num);
num = "12"; // 编译错误
console.log(num);