技术实践

为Vue3.0学习做准备

Vue3.0是基于TypeScript编写的,所以学习Vue3.0,先必须了解TypeScript

羊先生的头像
羊先生2021.03.15 · 6 分钟阅读 · 175 阅读
为Vue3.0学习做准备封面
文章正文还需 6 分钟

Vue3.0

Vue3.0是基于TypeScript编写的,所以学习Vue3.0,先必须了解TypeScript

Vue3.0+typescript案例

代码

基于 vue3 + vant3 的 H5移动端 demo-演示

TypeScript

Typed JavaScript at Any Scale.
添加了类型系统的 JavaScript,适用于任何规模的项目

TypeScript 是静态类型

类型系统按照「类型检查的时机」来分类,可以分为动态类型和静态类型。

动态类型是指在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。JavaScript 是一门解释型语言[4],没有编译阶段,所以它是动态类型,以下这段代码在运行时才会报错:

ts 复制代码
let foo = 1;
foo.split(' ');
// Uncaught TypeError: foo.split is not a function
// 运行时会报错(foo.split 不是一个函数),造成线上 bug

静态类型是指编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。TypeScript 在运行前需要先编译为 JavaScript,而在编译阶段就会进行类型检查,所以 TypeScript 是静态类型,这段 TypeScript 代码在编译阶段就会报错了:

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

TypeScript 是弱类型

类型系统按照「是否允许隐式类型转换」来分类,可以分为强类型和弱类型。

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

ts 复制代码
console.log(1 + '1');
// 打印出字符串 '11'
TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性,所以它们都是弱类型。

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

py 复制代码
print(1 + '1')
# TypeError: unsupported operand type(s) for +: 'int' and 'str'
若要修复该错误,需要进行强制类型转换:

print(str(1) + '1')
# 打印出字符串 '11'

安装 TypeScript

TypeScript 的命令行工具安装方法如下:

js 复制代码
npm install -g typescript

以上命令会在全局环境下安装 tsc 命令,安装完成之后,我们就可以在任何地方执行 tsc 命令了。

编译一个 TypeScript 文件很简单:

js 复制代码
tsc hello.ts

我们约定使用 TypeScript 编写的文件以 .ts 为后缀,用 TypeScript 编写 React 时,以 .tsx 为后缀

Hello TypeScript

我们从一个简单的例子开始。

将以下代码复制到 hello.ts 中:

ts 复制代码
function sayHello(person: string) {
    return 'Hello, ' + person;
}

let user = 'Tom';
console.log(sayHello(user));

然后执行

js 复制代码
tsc hello.ts

这时候会生成一个编译好的文件 hello.js:

ts 复制代码
function sayHello(person) {
    return 'Hello, ' + person;
}
var user = 'Tom';
console.log(sayHello(user));

在 TypeScript 中,我们使用 : 指定变量的类型,: 的前后有没有空格都可以。

上述例子中,我们用 : 指定 person 参数类型为 string。但是编译为 js 之后,并没有什么检查的代码被插入进来。

这是因为 TypeScript 只会在编译时对类型进行静态检查,如果发现有错误,编译的时候就会报错。而在运行时,与普通的 JavaScript 文件一样,不会对类型进行检查。

如果我们需要保证运行时的参数类型,还是得手动对类型进行判断:

ts 复制代码
function sayHello(person: string) {
    if (typeof person === 'string') {
        return 'Hello, ' + person;
    } else {
        throw new Error('person is not a string');
    }
}

let user = 'Tom';
console.log(sayHello(user));

let 是 ES6 中的关键字,和 var 类似,用于定义一个局部变量,可以参阅 let 和 const 命令

下面尝试把这段代码编译一下:

ts 复制代码
function sayHello(person: string) {
    return 'Hello, ' + person;
}

let user = [0, 1, 2];
console.log(sayHello(user));

编辑器中会提示错误,编译的时候也会出错:

js 复制代码
hello.ts:6:22 - error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

但是还是生成了 js 文件:

ts 复制代码
function sayHello(person) {
    return 'Hello, ' + person;
}
var user = [0, 1, 2];
console.log(sayHello(user));

这是因为 TypeScript 编译的时候即使报错了,还是会生成编译结果,我们仍然可以使用这个编译之后的文件。

如果要在报错的时候终止 js 文件的生成,可以在 tsconfig.json 中配置 noEmitOnError 即可。关于 tsconfig.json,请参阅官方手册(中文版)