Typescript的学习之路
-
早上面试被问到了TS相关的知识,下边就一起来复习一下
- Ts是以Js为基础的构建语言,一个js的超集(最主要的就是在js中引入了类型的概念),可以在任何支持js的平台中执行,ts不能被js解析器直接执行(ts需要编译成js)
- TS增加了什么:类型 、支持ES的新特性、添加ES不具备的新特性、丰富的配置选项、强大的开发工具
- TS增加了什么:类型 、支持ES的新特性、添加ES不具备的新特性、丰富的配置选项、强大的开发工具
- Ts中如果变量在声明的时候直接赋值,Ts可以自动对变量进行类型检测
- Ts中也可以声明函数的参数的类型,返回值的类型
-
function sum(a:number,b:number):number{ return a+b //return a+"123" 就会报错,因为上边限制了返回值的类型也应该是number }
Ts相对于js来说是严格的,当传参类型不对的时候会报错,返回值类型不对的时候也会报错
例如 sum(1,"123") sun(1,2,3) sum(1) 缺少参数或者增加参数都会报错 但是在编译的时候都是可以编译成功的
-
-
下边说说数据类型的声明
- Ts的对象数据声明
- {}用来指定对象中包含哪些属性
- 语法:{属性名:属性值,属性名:属性值}
- 在属性名的后边加?,表示属性是可选的
-
let a = {name:string,age?:number} a = {name:"张三",age:18}
- [propName:string]:any 表示任意类型的属性,数量也不限制
-
let c :{name:string,[propName:string]:any } c= { name:"张三", age:18, size:9 }
- Ts函数类型声明
- 语法:(形参:类型,形参:类型 ...)=>返回值
-
let a :(a:number,b:number)=>number
- 数组的类型声明
- 类型 [ ]
- Array <类型>
-
let a :string[] a= ["张三",“李四”] let b:Array<number> b = [1,2,3,5,8]
- 元组:元组就是固定长度的数组
-
let a:[string,string] a=[1,2]
-
- enum:枚举
-
enum Gender{ Male, Female } let a:{name:string,gander:Gender} a = {name:"张三",gander::Gender.Male}
-
- 类型的别名
-
type myType = 1|2|3 let a :myType let b:myType a= 1 b=3
-
-
TS的编译选项
- tsconfig.json是ts编译器的配置文件,ts编译器可以根据她的信息来对代码进行编译
先来看看我的项目结构
- 当我们配置好tsconfig.json文件的时候,我们就可以在项目下直接舒勇tsc来对指定的ts文件进行编译,下边我们就来说具体的编译文件的选项
{ /* tsconfig.json是ts编译器的配置文件,ts编译器可以根据它的信息来对代码进行编译 "include" 用来指定哪些ts文件需要编译 路径:** 表示任意目录 *表示任意文件 "exclude" 不需要被编译的文件目录 */ "include": [ "./src/**/*" ], // "exclude": [ // "./src/hello/**/*" // ], /* "compilerOptions" 编译器的选项 */ "compilerOptions": { //target 用来指定ts被编译为的ES的版本 //'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext' "target": "es6", //module 指定要使用的模块化规范 //'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'esnext'. "module": "es6", //用来指定编译后文件所在的目录 "outDir": "./dist", //将代码合并为一个文件 //设置outTile之后,所有的全局作用域中的代码会合并到同一个文件中 // "outFile": "./dist/app.js", //是否对js文件进行编译,默认置为false "allowJs": false, //是否检查js代码是否符合语法规范 默认置为false "checkJs": false, //是否移除注释 "removeComments": false, //不生成编译后的文件 "noEmit": false, //当有错误是不生成编译后的文件 "noEmitOnError": true } }
-
当然下边的内容也是可以在
“compilerOptions“属性下边的添加的,这里就以图片说明
-
Webpack配置项目
- 创建项目
-
在终端输入 npm init -y (初始化项目,生成package.json)
- 安装依赖 npm i -D webpack webpack-cli typescript ts-loader
- 在项目下创建webpack.config.js文件,这就是webpack的配置信息
//引入一个包 js的包 方便后边的拼接路径 const path = require('path') //webpack中的所有配置信息都应该写在module.exports中 module.exports = { //入口文件 entry: "./src/index.ts", //指定打包文件所在的目录 output: { //指定打包文件的目录 path: path.resolve(__dirname,'dist'), //打包之后的文件 filename: "bundle.js" }, //指定webpack打包时使用的模板 module: { //指定要加载的规则 rules: [ { //指定的是规则生效的文件 test: /\.ts$/, //指定所有ts结尾的文件 //要使用loader 刚刚装的依赖 对ts文件进行编译 use: 'ts-loader', //要排除的文件 这里是排除依赖文件里边的 exclude: /node-modules/ } ] } }
- 创建ts编译文件,tsconfig.json
{ "compilerOptions": { "module": "ES2015", "target": "ES2015", "strict": true //严格模式 } }
- 在package.json配置打包的命令
- 到这里Ts的项目的最基本的配置就完成了,目录结构如下
- 我们在终端就可以运行 npm run build 对这个项目进行打包了
webpack高级配置
- 在终端输入 npm i -D html-webpack-plugin (帮助我们自动的生成html文件),安装完成之后,会在package.json自动配置上
- 我们再去webpack.config.js进行配置
- 然后运行npm run build ,效果图如下:
最智能的是,它会自动将我们打包好的js文件自动引入到html文件中
- 但是这样自动生成的html这样设置title不能解决复杂的网页结构,那我们就在src目录下创建一个index.html,然后在webpack.config.js中间这个设置为模板
- 上边我们介绍了webpack的打包,现在打包是自动生成的,那我们的项目如何修改之后,浏览器会自动显示最新的效果呢?
- 终端输入 npm i -D webpack-dev-server
- 安装完成之后,再去webpack.json中添加启动命令:
但是这样配置完成之后,在我们使用npm run serve 的时候会弹出警告的,说我们没有设置开发的环境,那在这里需要添加我们的开发环境,我在这里直接添加了生产的环境,其实还有“development” 开发者环境 、“none”这三种环境 - 接下来我们就可以在终端输入 npm run serve 启动当前的项目,效果如下:
- 这样启动项目之后,后边我们在项目中再修改代码,保存之后,所打开的网页就会自动更新最新的代码效果 (关掉服务 ctrl+c )
- 上边已经说过了,我们运行 npm run build 会自动打包到dist目录下,那我们假如一个这样的场景,第一次打包了两个文件,后边我们修改代码,修改配置按道理会打包一个文件,但由于原来是两个,现在再打包只是更新,还是两个
综合上述问题,我们就需要在每一次打包的时候先清空dist目录,然后在打包,其实webpack为我们提供了插件 - npm i -D clean-webpack-plugin
- 然后在webpack.config.js的文件中引入
- 上述配置完成之后,在我们的项目当中其实还存在一个问题,比如现在需要在index.ts文件里边去引入另一个ts文件(import { m1 } from ' ./ m1'),这样引入的时候,就相当于m1.ts作为一个模块被引入,但是,我们的项目现在没有配置ts可以作为模块引入
- 下边我们就需要配置,继续进入到webpack.config.js设置
- 到这里,我们的webpack.config.js就配置完成了,最终的代码如下
//引入一个包 js的包 方便后边的拼接路径 const path = require('path') //引入html插件 const HTMLWebpackPlugin = require('html-webpack-plugin'); //引入clean插件 const {CleanWebpackPlugin} = require('clean-webpack-plugin') //webpack中的所有配置信息都应该写在module.exports中 module.exports = { //入口文件 entry: "./src/index.ts", //指定打包文件所在的目录 output: { //指定打包文件的目录 path: path.resolve(__dirname,'dist'), //打包之后的文件 filename: "bundle.js" }, //指定webpack打包时使用的模板 module: { //指定要加载的规则 rules: [ { //指定的是规则生效的文件 test: /\.ts$/, //指定所有ts结尾的文件 //要使用loader 刚刚装的依赖 对ts文件进行编译 use: 'ts-loader', //要排除的文件 这里是排除依赖文件里边的 exclude: /node-modules/ } ] }, //配置webpack插件 plugins: [ new CleanWebpackPlugin(), new HTMLWebpackPlugin({ // title: "自定义title" //修改生成的html的title 但是如果我们有多个html文件,就没有办法设置了 //那我们就在src目录下创建一个html文件作为html 的模板 template: "./src/index.html" }) ], //用来实质引入模块 resolve: { extensions: ['.ts','.js'] } }
- 上边我们算是基本的配置完成了,但是,在我们的实际的项目中,我们要考虑到兼容性的问题,所以,我们还需要在打包的时候做好浏览器的兼容,虽然我们在tsconfig.json中做了语法的兼容处理,但是这个这能是处理简单的语法转换,如果想promise这种语法,这个配置就没有办法去兼容和转化了,所以,我们需要在webpack打包的时候将代码转换成浏览器兼容的代码
- npm i -D @babel/core @babel/preset-env babel-loader core-js
- 然后在webpackage.config.js中添加配置
- 上边我们已经做好了浏览器的兼容问题,但是,我们现在将我们的程序运行到IE浏览器中还是可能会报错,因为在IE的浏览器中不支持箭头函数,所以,我们要想让我们的程序兼容IE浏览器,那我们就在打包的时候取消箭头函数的产生,这里所说的箭头函数不是程序里边的箭头函数,程序里边的箭头函数在经过我们的兼容现有的配置就会转化成IE兼容的普通函数,这里所产生的箭头函数实际是webpack本身在编译的时候产生的,所以,我们需要在webpack打包的配置中再进行设置
不设置的时候webpack自动添加的箭头函数
设置之后,取消了箭头函数的产生就可以在IE中使用程序了
- 到这里,webpack的配置我们就完成的比较全面了,下边来看看每个文件的最终代码
webpack.config.js
//引入一个包 js的包 方便后边的拼接路径 const path = require('path') //引入html插件 const HTMLWebpackPlugin = require('html-webpack-plugin'); //引入clean插件 const {CleanWebpackPlugin} = require('clean-webpack-plugin') //webpack中的所有配置信息都应该写在module.exports中 module.exports = { //入口文件 entry: "./src/index.ts", //指定打包文件所在的目录 output: { //指定打包文件的目录 path: path.resolve(__dirname,'dist'), //打包之后的文件 filename: "bundle.js", //告诉webpack不使用箭头函数 environment:{ arrowFunction:false } }, //指定webpack打包时使用的模板 module: { //指定要加载的规则 rules: [ { //指定的是规则生效的文件 test: /\.ts$/, //指定所有ts结尾的文件 //要使用loader 刚刚装的依赖 对ts文件进行编译 use: [ { //配置babel loader:"babel-loader", //设置babel options: { //设定预定义的环境 presets:[ [ //指定环境的插件 "@babel/preset-env", //配置信息 { //要兼容的目标浏览器 targets:{ "chrome":"88", //意思就是要兼容谷歌浏览器88版本 "ie":"11" //兼容ie11 }, //指定corejs的版本 "corejs":"3", //使用corejs的方法 “usage”表示按需加载 "useBuiltIns":"usage" } ] ] } }, 'ts-loader' ], //要排除的文件 这里是排除依赖文件里边的 exclude: /node-modules/ } ] }, //配置webpack插件 plugins: [ new CleanWebpackPlugin(), new HTMLWebpackPlugin({ // title: "自定义title" //修改生成的html的title 但是如果我们有多个html文件,就没有办法设置了 //那我们就在src目录下创建一个html文件作为html 的模板 template: "./src/index.html" }) ], //用来实质引入模块 resolve: { extensions: ['.ts','.js'] } }
package.json
{ "name": "demo1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode production", "serve": "webpack server --mode production" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.17.5", "@babel/preset-env": "^7.16.11", "babel-loader": "^8.2.3", "clean-webpack-plugin": "^4.0.0", "core-js": "^3.21.1", "html-webpack-plugin": "^5.5.0", "ts-loader": "^9.2.6", "typescript": "^4.5.5", "webpack": "^5.69.1", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.7.4" } }
做最好的自己,不努力永远看不到自己的光环。别在该努力的年纪享乐,就不会在该享乐的年纪吃苦!