前言
近几年前端对 TypeScript 的呼声越来越高,尤大大更是将Vue3用TypeScript重写了一遍, TypeScript 似乎也变成了一个必须要会的技能,不然你想看看Vue3源码都寸步难行,知乎上经常见到像『自从用了 TypeScript 之后,再也不想用 JavaScript 了』、『只要你用过 ES6,TypeScript 可以几乎无门槛接入』、『TypeScript可以在任何场景代替 JS』这些类似的回答,抱着听别人说不如和我一起来学习TypeScript吧,最近参加了第一届字节前端青训营,TypeScript学习也是从这开始,这篇文章是一篇学习笔记,如有记录错误欢迎大佬们指出~🧐
一、TypeScript基础
1.1 开发环境搭建
初始化第一个TypeScript项目
npm init -y npm install --save-dev typescript # 最新稳定版 npm install --save-dev typescript@next # 尝鲜版 复制代码
创建tsconfig.js文件
方法一:首先创建.ts
文件,然后在VsCode的右下角点击TypeScript版本号,然后会出现下拉菜单,点击创建tsconfig
选项,这样tsconfig
文件就创建好啦~
tsconfig.json
文件如下👇:
{ "compilerOptions": { "module": "commonjs", "target": "es2020", "jsx": "preserve", "strictFunctionTypes": true, "sourceMap": true }, "exclude": [ "node_modules", "**/node_modules/*" ] } 复制代码
方法二:进入node_modules/.bin/tsc 然后运行命令--init locale zh-CN
,这样也能生成tsconfig
文件~
选择TypeScript版本
我们选择
node_modules
目录下的那个版本。
选择版本之后,根目录下会生成
.vscode
文件夹,里面会有settings.json
文件。
1.2 工具
TS Playground
TypeScript官方为我们提供了测试ts代码的工具:TS Playground。如下图所示:👇
Equal<x,y>
该工具可以查看两个类型名的类型是否相等。
1.3 预备知识
TS与JS的关系
我们要清楚的是TypeScript
是JavaScript
的超集,TypeScript
提供了所有JavaScript特性,并在其上层增加了TypeScript
类型系统。
这个类型系统被设计为”可选的“。这就意味着:所有合法的
JavaScript
代码都是合法的TypeScript
代码.
TS的编译过程
‘TS的类型检查’与‘生成JS’是两个独立的过程;类型检查出错不影响生成
JavaScript
代码! 因此它和C,C++等语言的编译过程是不同的!
类型系统
我们要清楚 TS采用的是结构类型系统,那么什么是结构类型系统呢?
结构类型系统(Structural Type System) 通过类型的实际结构确定两个类型是否相等或兼容(TypeScript,Haskell,Go,...) 名义类型系统(Nominal Type System) 通过类型的名称确定两个类型是否相等(C,C++,Java,C#,Rust,...)
类型注解
TS的类型注解也是我们要知道的,它和其他语言有所不同,看下面代码:👇
// C++ 放在前面 int printf( const char*, ...); // Objc 放在前面,加括号 - (id)initWithInt:(int)value; // Julia 放在后面,加双冒号 commission(sale::Int,rate::Float64)::Float64 // TypeScript 也放在后面,加双冒号 function log(message: string): void 复制代码
类型与集合的关系
具体看见下表
TypeScript term | Set term |
nerver | empty set |
Lieral type | Single element set |
Value assignable toT | Value∈T(member of) |
T1 assignable to 2 | T1⊆T2(subset of) |
T1 extends T2 | T1⊆T2(subset of) |
T1|T2 | T1∪T2 |
T1&T2 | T1∩T2(intersection) |
unknown | Universal set |
类型别名
在JS中:可以勇let、const、var声明变量或常量
在TS中:可以勇type为类型声明别名
类型别名和let变量类似,也采用块级作用域。所以,同一作用域内不能重名。
类型拓宽与收窄
类型拓宽(Type Widening):
当你把用字面量赋值给let、var变量使,TS不用字面量类型作为该变量的类型。而是从字面量类型拓宽到相应的更宽泛的类型。这个过程叫做类型拓宽。
类型收窄(Type Narrowing):
在某些情况下,TS可以更加确定变量的类型,此时它将会将变量类型收窄。
TS试图在类型确定性与灵活性之前取得平衡。 TS提供一系列方法来帮助收窄类型,以提高类型的确定性:
- null check
- ad const
- instanceof
- typeof
- 属性检查
- Tagged Union
- 用户类型守卫
- 代码流
用let var声明变量时,TS认为变量未来会发生改变,所以将类型推断为相应宽泛的类型。 用const声明变量时,TS知道常量是不会改变的,会将类型推断为最窄的字面量类型。
值类型与类型空间
我们可以这样理解,所谓的类型空间就是编译期存在的各种类型,它是由TypeScript
的编译器里面的tsc创建的,值空间是由JS
引擎比如V8
引擎创建的,里面存在运行时的各种值。
只包含类型声明的namespace不会产生JS代码,不会引入变量。
instanceof操作符只作用于值空间。
如何判断符号在哪个空间呢?
- 转译后消失的代码——>类型空间
- 作为类型注解、别名的符号——>类型空间
- 类型断言后的符号——>类型空间(target as/is HTMLElement)
- const,let,var后面的符号——>值空间
- class,enum,namespace后的符号——>值空间+类型空间
TS中的类型层次
可见下图👇:
下层类型的值可以赋给上层类型的变量/常量
unknown类型的变/常量可以指向任何类型的值
不存在never类型的变量(nerver是空集)
对比不同语言的 Top Type和 Bottom Type
好啦,到这,我们学习TypeScript的预备知识就介绍完啦~
最后
⚽好啦,到这,我们学习TypeScript的预备知识就介绍完啦~
⚾后面会更新TypeScript的基础知识噢!感兴趣的同学可以点赞关注+收藏,更多精彩知识正在等你~