玩转Typescript(一):TypeScript 入门

372 阅读5分钟

这是我参与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);