一、TypeScript初体验

TypeScript最终会被编译成JavaScript代码:

1
2
3
4
5
const message: string = 'jack';
function demo(params: string) {
console.log(params.length);
}
demo('aaaa');

tsc 文件名

将ts文件编译为js文件

index.html中引入js以执行

二、环境搭建

每次编写ts文件在手动进行tsc编译过于麻烦

应该搭建自动编译环境

  • 方式一:通过webpack,配置本地的TypeScript编译环境和开启一个本地服务,可以直接运行在浏览器上;做项目时常用

  • 方式二:通过ts-node库,为TypeScript的运行提供执行环境,学习TypeScript时常用;

    • npm install ts-node -g
    • npm install tslib @types/node -g
    • ts-node math.ts
  • 方式三:创建tsconfig.json文件并进行监听:

    • 创建tsconfig.json文件 tsc –init 生成配置文件

    • tsconfig.json配置文件中,修改outDir配置项,取消注释然后修改为.js

    • vscode中,点击终端-运行任务-ts监视 进行监听

三、类型声明

在TypeScript中定义变量需要指定标识符的类型。

完整的声明格式如下:

1
var/let/const 标识符: 数据类型 = 赋值;

声明了类型后TypeScript就会进行类型检测,声明的类型可以称之为类型注解

比如我们声明一个message,完整的写法如下:

1
const message:string = 'jack'

注意:这里的string是小写的,和String是有区别的

  • string是TypeScript中定义的字符串类型,
  • String是ECMAScript中定义的一个类

在tslint中并不推荐使用var来声明变量:

  • 可见,在TypeScript中并不建议再使用var关键字了,主要原因和ES6升级后let和var的区别是一样的,var是没有块级作用域的,会引起很多的问题。

类型推导

开发中,有时候为了方便起见并不会在声明每一个变量时都写上对应的数据类型,更希望可以通过TypeScript本身的特性帮助我们推断出对应的变量类型:

1
2
3
4
let obj = 'aaa';

//报错 不能将number类型分配给string类型
// obj = 1;

在一个变量第一次赋值时,会根据后面的赋值内容的类型,来推断出变量的类型

上面的message就是因为后面赋值的是一个string类型,所以message虽然没有明确的说明,但是依然是一个string类型。

四、数据类型

JavaScript与TypeScript共有

number

1
2
3
4
5
6
const num1: number = 100;
const num2: number = 0b100;
const num3: number = 0o100;
const num4 = 0x100;
//100 4 64 256
console.log(num1, num2, num3, num4);

string

1
2
3
4
5
6
7
8
9
const name = "jack"
const age = 20

//名字是jack,年龄是20
const person = `名字是${name},年龄是${age}`
console.log(person);

//解决作用于冲突
export = {}

boolean

1
2
3
let flag:boolean = false;
flag = true;
flag = 20 > 39;

Array

1
2
3
4
5
6
7
8
9
10
11
12
13
//指定数组的里的数据为字符串类型
let names: string[] = [];

//另一种写法 -- 不推荐
const names2: Array<string> = [];

names.push('aaa', 'bbb');

//会报错,只能是string类型
names.push(123)

//[ 'aaa', 'bbb' ]
console.log(names);

Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let obj:object = {
name: 'jack',
age: 20,
};
//添加注解会报错 --- 读取不到内部的属性
//console.log(obj.name);


let obj1 = {
name: 'jack',
age: 20,
};
//不手动添加注解可以读取到
//jack
console.log(obj1.name);

Symbol

1
2
3
4
5
6
7
const s1 = Symbol('title');
const s2: symbol = Symbol('title');

let obj = {
[s1]: '人',
[s2]: '老师',
};

null与undefined

1
2
let n:null = null;
const u: undefined = undefined;

TypeScript独有数据类型

any

在某些情况下,确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候我们可以使用any类型(类似 于Dart语言中的dynamic类型)

any类型有点像一种讨巧的TypeScript手段:

  • 我们可以对any类型的变量进行任何的操作,包括获取不存在的属性、方法;
  • 我们给一个any类型的变量赋值任何的值,比如数字、字符串的值;
1
2
3
4
5
6
7
let msg: any = 'aaa';

msg = 111;

msg();

msg.length;
  • 某些情况的处理过于繁琐不希望添加规定的类型注解,或者在引入一些第三方库时,缺失了类型注解,这个时候 我们可以使用any
  • 包括在Vue源码中,也会使用到any来进行某些类型的适配;
  • 但是any是不安全的的,一般建议不用

unknown

unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function demo1() {
return 1;
}
function demo2() {
return 'aaa';
}
//flag可能为true也可能为false
let flag = true;
//any类型也可以,但是any相对不太安全
/*两者区别
1、any类型的可以在赋值给任意其他类型
2、unknown只能再赋值给any或者unknown类型
*/
let result: unknown;
if (flag) {
result = demo1();
} else {
result = demo2();
}

  • any类型的可以在赋值给任意其他类型
  • unknown只能再赋值给any或者unknown类型

void

void通常用来指定一个函数是没有返回值的,那么它的返回值就是void类型

我们可以将null和undefined赋值给void类型,也就是函数可以返回null或者undefined,同时也是void类型

1
2
3
4
5
6
function sum(num1: number, num2: number): void {
console.log(num1 + num2);
// return undefined
// return null;
}
//sum为void类型

never

never 表示永远不会发生值的类型,比如一个函数:

如果一个函数中是一个死循环或者抛出一个异常,那么这个函数会返回东西吗? 不会,

那么写void型或者其他类型作为返回值类型都不合适,我们就可以使用never类型;

1
2
3
4
5
6
7
8
function demo(): never {
//死循环
while (true) {}
}

function demo1():never {
throw new Error()
}

truple

tuple是元组类型,很多语言中也有这种数据类型,比如Python、Swift等。

那么tuple和数组有什么区别呢?

  • 首先,数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组中)
  • 其次,元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型;
1
2
3
const persons: [string, number, number] = ['jack', 20, 1.88];
console.log(persons[0]);
console.log(persons[1]);