TypeScript学习笔记(一)

TypeScript简介

  1. TypeScript是JavaScript的超集。
  2. 它对JS进行了扩展,向JS中引入了类型的概念,并添加了许多新的特性。
  3. TS代码需要通过编译器编译为JS,然后再交由JS解析器执行。
  4. TS完全兼容JS,换言之,任何的JS代码都可以直接当成JS使用。
  5. 相较于JS而言,TS拥有了静态类型,更加严格的语法,更强大的功能;TS可以在代码执行前就完成代码的检查,减小了运行时异常的出现的几率;TS代码可以编译为任意版本的JS代码,可有效解决不同JS运行环境的兼容问题;同样的功能,TS的代码量要大于JS,但由于TS的代码结构更加清晰,变量类型更加明确,在后期代码的维护中TS却远远胜于JS。
    在这里插入图片描述

TypeScript 开发环境搭建

  1. 下载Node.js

  2. 安装Node.js

  3. 使用npm全局安装typescript
    (1)进入命令行
    (2)输入:npm i -g typescript

  4. 创建一个ts文件

  5. 使用tsc对ts文件进行编译
    (1)进入命令行
    (2)进入ts文件所在目录
    (3)执行命令:tsc xxx.ts(会将ts文件转换成js文件,添加到目录中)

基本类型

1、类型声明

  • 类型声明是TS非常重要的一个特点

  • 通过类型声明可以指定TS中变量(参数、形参)的类型

  • 指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错

  • 简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值

  • 语法:

	let 变量: 类型;
	
	let 变量: 类型 =;
	
	function fn(参数: 类型, 参数: 类型): 类型{
	    ...
	}

2、自动类型判断

  • TS拥有自动的类型判断机制
  • 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
  • 所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明

栗子:
(1)声明一个变量并指定它的类型

	// 声明一个变量a,同时指定它的类型为number
	let a: number
	// a类型为number,在以后的使用中a的值只能是数字
	a = 10
	a = 'hello'  //报错,不能赋字符串
	let b: string
	b = 'hello'

(2)声明完变量直接赋值(但这种方法不常用,原因见(3))

	let c: boolean = true

(3)如果变量的声明与赋值是同时进行的,TS可以自动对变量进行类型检测(此时就不用像上一步那样指定类型)

	let c = true	 //相当于声明了 c 是 Boolean类型
	c = false
	c = 123   //此行会报错

(4)类型声明的优势主要体现在对函数参数的类型声明上 !

js中对于函数的声明:

	// js函数是不考虑参数的类型和个数的
	function sum(a,b) {
	    return a + b
	}
	
	sum(22, '88', 12)  //js当参数是字符串,或者 有多个参数时都不会报错
	console.log(sum);

ts 中对于函数的声明:

	// ts
	function sum(a:number, b:number){
	    return a + b
	}
	sum(123,'456')   //报错 
	// 指定函数返回值的类型
	function sum(a:number, b:number): number{
	    return a + b
	}

3、类型

类型例子描述
number1, -33, 2.5任意数字
string‘hi’, “hi”, hi任意字符串
booleantrue、false布尔值true或false
字面量其本身限制变量的值就是该字面量的值
any*任意类型
unknown*类型安全的any
void空值(undefined)没有值(或undefined)
never没有值不能是任何值
object{name:‘孙悟空’}任意的JS对象
array[1,2,3]任意JS数组
tuple[4,5]元素,TS新增类型,固定长度数组
enumenum{A, B}枚举,TS中新增类型

几个重要的类型举例:

(1)字面量

	// 可以直接使用 字面量 进行类型声明
	let num: 10;
	// 但此时 num的值只能为10,不能改成其他的
	num = 10    //不报错
	num = 11   //报错

(2)可以使用 | 来连接多个类型(联合类型)

	let str: 'male' | 'female'
	
	str = 'male'
	str = 'female'
	str = 'hello' //报错
	// 也可以直接指定类型
	let s: boolean | string
	s= true
	s= 'hello'

(3)any 任意类型,一个变量设置为any,相当于对该变量关闭了类型检测
(与js一样了,所以在开发中不建议使用)

	let d:any
	//d 可以被赋值为任意的数据类型
	d = 10
	d = 'hello'
	d = true
	// 声明变量如果不指定类型,TS解析器会自动判断变量的类型为any(隐私any,也要避免使用)
	//let d

注:声明变量如果不指定类型,TS解析器会自动判断变量的类型为any(隐式any,也要避免使用)

(4)unknown

如果变量的类型不确定用unknown。unknown表示未知类型的值
	let e: unknown
	e = 20
	e = 'hello'
	e = true

与any的区别:

  • any类型的值 可以赋值给任意变量并且不会报错
let d
d = true
let st: string
// d 的类型是any(此时的值为true--Boolean类型),它可以赋值给任意变量并且不会报错。
// 这就会导致此时st的值会受到影响。本来应该是string却变成了Boolean类型,并且没有报错
st = d   //这里不会报错,但实际上这样赋值是不对的
  • unknown类型的值 不能直接赋值给其他变量
	let e: unknown
	e = 'hello'
	let st: string
	st = e    //会报错

将unknown类型的值 赋值给其他变量,有两种方式:

  1. 先进行类型检测再赋值
	if(typeof e === 'string'){
	    st = e
	}
  1. 类型断言–用来告诉解析器 变量的实际类型
    断言有两种声明方式:
	st = e as string  //告诉解析器,这个 e 是string类型。这样就可以赋值了
	st = <string>e

(5)指定函数的返回值

	function fn(): number{}
	function fn(): string{}
	function fn(): void{}
	function fn(): never{}
  1. void
    void用来表示空,以函数为例,表示没有返回值的函数
    不写返回值,或者返回的是 null / undefined 均不会报错
function fn(): void{
    // return null
    //return undefined
}
  1. never
    表示永远不会返回结果(用于抛出异常,不常用)
	function fn2(): never{
	    throw new Error('报错了')
	}

(6)object

  1. object表示一个js对象(不常使用),let o: object
    因为 js 对象有更简单的表示方式:o = {} 或者 o = function(){}
  2. 在声明对象时 常用于 指定对象中属性的类型:
	// 指定对象中可以包含哪些属性
	let o1: {name: string, age?: number}
	
	o1 = {name:'sunwukong',age:18}
  • 语法:{属性名:属性值,属性名:属性值}
  • 在属性名后加上 ?,表示属性是可选的。(在后续赋值时可以不指定 age。但必须指定name)
  1. 如果想在 一个对象中 增加多个可选的属性,可以使用:

    [propName: string]: any 表示任意类型的属性

// [propName: string]: any 表示任意类型的属性
let o2: {name:string, [propName: string]: any}
o2 = {name:'猪八戒', age:18, gender:'男'}
  1. 函数结构的类型声明
  • 语法:(形参:类型,形参:类型…) => 返回值
	let o3: (a:number,b: number) => number
	o3 = function(n1,n2): number{
	    return n1 + n2
	}

指定 形参以及返回值 的类型

(7)数组的类型声明

两种方式:

  1. 类型[]
	// string[] 表示字符串数组
	let arr: string[]
	arr = ['a','b','c']    
	// arr = ['a','b','c',1,2]    //报错
	
	// number[] 表示数值数组
	let f: number[]
  1. Array<类型>
	let g: Array<number>
	g = [1,2,3]

(8)tuple(元组):固定长度的数组

  • 语法: [类型,类型,类型…]
	let h: [string,string]
	// h = ['hello', 'hi', 123]  //报错
	h = ['hello', 'hi']

(9)enum (枚举)

  • 适用于像性别这种值固定的情况,不用再指定 男为0,女为1。直接使用 Gender.xxx
	// 定义枚举
	enum Gender{
	    Male,
	    Female 
	}
	
	let i: {name:string, gender:Gender}
	i = {
	    name:'孙悟空',
	    gender:Gender.Male
	}
	
	console.log(i.gender === Gender.Male);

(10)&表示同时

	let j: {name:string} & {age:number}
	// j = {name:'孙悟空'}  //报错
	j = {name:'孙悟空', age:80}

(11)类型的别名

  • 可以将需要反复用到的类型给他起个别名,方便后续使用
	// 类型的别名
	type myType = 1|2|3|4|5
	let k: myType
	let l: myType
	
	k = 1
	//k = 9   //报错

编译选项

1、自动编译文件

(1)编译文件时,使用 -w 指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译。

(2)示例:tsc xxx.ts -w

2、自动编译整个项目

(1)如果直接使用tsc指令,则可以自动将当前项目下的所有ts文件编译为js文件。

(2)但是能直接使用tsc命令的前提时,要先在项目根目录下创建一个ts的配置文件 tsconfig.json(创建方式:在终端执行 tsc --init

(3)tsconfig.json是一个JSON文件,添加配置文件后,只需 在终端 输入 tsc 命令即可完成对整个项目的编译(将ts 转换成 js)。也可使用 tsc -w 来对监视所有文件的变化。

(4)tsconfig.json的配置选项:

  • include:定义希望被编译文件所在的目录(指定哪些 ts 文件需要被编译)
  1. 默认值:[“**/*”] ,**表示任意目录,*表示任意文件
  2. 示例:"include":["src/**/*", "tests/**/*"]
  3. 上述示例中,所有src目录和tests目录下的文件都会被编译
  • exclude:定义需要排除在外的目录
  1. 默认值:["node_modules", "bower_components", "jspm_packages"]
  2. 示例:"exclude": ["./src/hello/**/*"]
  3. 上述示例中,src下hello目录下的文件都不会被编译
  • extends:定义被继承的配置文件
  1. 示例:"extends": "./configs/base"
  2. 上述示例中,当前配置文件中会自动包含config目录下base.json中的所有配置信息
  • files:指定被编译文件的列表,只有需要编译的文件少时才会用到
  1. 示例:
	"files": [
	    "core.ts",
	    "sys.ts",
	    "types.ts",
	  ]
  1. 列表中的文件都会被TS编译器所编译
  • compilerOptions
  1. 编译选项是配置文件中非常重要也比较复杂的配置选项
  2. 在compilerOptions中包含多个子选项,用来完成对编译的配置:
{
  "include": ["./src/**/*"],
  // 编译器选项
  "compilerOptions": {
    // target 用来指定ts 被编译的 js 版本
    // 可选值:"ES3"(默认), "ES5", "ES6", "ES2015", "ES2016", "ES2017", "ES2018", "ES2019", "ES2020", "ES2021", "ES2022", "ESNext"
    "target": "es6",
    // module 指定要使用的模块化规范
    // 可选值:"CommonJS", "AMD", "System", "UMD", "ES6", "ES2015", "ES2020", "ESNext", "None", "ES2022", "Node16", "NodeNext"
    "module": "system",
    // lib 用来指定项目中所使用的库(一般不需要设置,有默认值)
    // 可选值:ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext、DOM、WebWorker、ScriptHost ......
    "lib": ["ES6"],
    
    //outDir 指定编译后 js文件所在的目录
    "outDir": "./dist",
    
    // outFile 将代码 合并成一个文件(将所有ts文件编译后的代码都放到 app.js中)
    "outFile": "./dist/app.js",

    // allowJs 是否对js文件进行编译,默认为false
    "allowJs": true,
    // checkJs 是否检查js代码是否符合语法规范,默认是false
    "checkJs": true,

    // removeComments 是否移除注释,默认false不移除
    "removeComments": true,
    
    // noEmit ,默认false不生成编译后的文件
    "noEmit": true

    // noEmitOnError,当有错误时不生成编译后的文件(false)
    "noEmitOnError": true
  }
}

与语法检查相关的配置:

{
 	 ......
    // strict 所有严格检查的总开关。为true时后面的几个配置项都默认为true,可以不写。(一般都设为true)
    "strict": true,

    // js文件设置严格模式方式:在文件的开头添加 "Use Strict"
    // alwaysStrict 设置编译后的文件是否使用严格模式,默认false
    "alwaysStrict": true,

    // noImplicitAny 不允许隐式的any类型,默认false
    "noImplicitAny": true,

    // noImplicitThis 不允许不明确类型的this,默认false
    "noImplicitThis": true,

    // strictNullChecks 严格地检查空值,默认false
    "strictNullChecks": true
  }
}

webpack

1、通常情况下,实际开发中我们都需要使用构建工具对代码进行打包,TS同样也可以结合构建工具一起使用,下边以webpack为例介绍一下如何结合构建工具使用TS。

2、步骤:

(1)初始化项目

  • 进入项目根目录,执行命令 npm init -y
  • 主要作用:创建package.json文件

(2)下载构建工具

在终端执行:npm i -D webpack webpack-cli webpack-dev-server typescript ts-loader clean-webpack-plugin

工具名作用
webpack构建工具webpack
webpack-cliwebpack的命令行工具
webpack-dev-serverwebpack的开发服务器(内容改变时会自动重新编译并执行)
typescriptts编译器
ts-loaderts加载器,用于在webpack中编译ts文件
html-webpack-pluginwebpack中html插件,用来自动创建html文件
clean-webpack-pluginwebpack中的清除插件,每次构建都会先清除目录 (清除以前生成的文件)

注:

  • 安装 webpack 后,需要在package.json中添加 "build":"webpack"

  • 安装 webpack-dev-server 后,需要在package.json中添加 "start": "webpack serve --open chrome.exe"(表示 启动webpack服务器并使用谷歌浏览器去打开网页。通过 npm start 调用)
    如果使用VSCode 会报404. 使用 "start": "webpack serve --open --mode development"解决

  • 新版的webpack 不需要使用清除插件,在 output 中 添加 clean:true就行

(3)基础配置

webpack.config.js:

// 引入包,帮助拼接路径
const path = require('path')
// 引入html插件,用于生成html文件
const HTMLWebpackPlugin = require('html-webpack-plugin')
// 引入清除插件
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

// webpack中的所有配置信息都应该写在module.exports中
module.exports = {
    // 指定入口文件
    entry:'./src/index.ts',

    // 指定打包文件所在的目录
    output:{
        // 指定打包文件的目录(利用path 将路径拼接起来)
        path:path.resolve(__dirname,'dist'),
        // 打包后文件的名字
        filename:'bundle.js'
    },

    // 指定webpack打包时要使用的模块
    module:{
        // 指定要加载(loader)的规则
        rules:[
            {
                // test 指定规则生效的文件(对谁进行编译--这里是以.ts结尾的文件)
                test: /\.ts$/,
                // 使用什么加载器来处理上面的文件。ts文件对应的就是 ts-loader
                use:'ts-loader',
                // 要排除的文件(不进行处理的文件,通常是node-modules)
                exclude: /node-modules/
            }
        ]
    },

    // plugins 配置 webpack 的插件
    plugins:[
        // 执行 npm run build 后,webpack会自动生成一个导入了 转译后的js文件的 html文件
        // new HTMLWebpackPlugin(),   //()不写东西,会使用默认的html配置
        // 给它指定配置
        new HTMLWebpackPlugin({
            // title:'这里定义html文件的title',   这种方式适用于单个文件
            // 如果想让多个html文件的结构一致,可以自己在某个目录下新建一个html文件并写好结构,将其作为模板
            template:"./src/index.html"
        }),
        // 使用清除插件。注:新版的webpack 可以直接在 output中设置 clean:true 就行
        new CleanWebpackPlugin()
    ],

    // 用来设置引用模块(哪些文件可以作为模块使用)
    resolve:{
        extensions:['.ts','.js']  //以.ts 和.js 结尾的文件
    }
}

备注:__dirname 可以用来动态获取当前文件所属目录的绝对路径。

新建 tsconfig.json:

	{
	    "compilerOptions": {
	        "module": "ES2015",
	        "target": "ES2015",
	        "strict": true
	    }
	}

在package.json添加如下配置:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack", 
    "start": "webpack serve --open --mode development"
  },

(4)在src下创建ts文件,并在并命令行执行npm run build对代码进行编译,或者执行npm start来启动开发服务器

Babel

1、经过一系列的配置,使得TS和webpack已经结合到了一起,除了webpack,开发中还经常需要结合babel来对代码进行转换以使其可以兼容到更多的浏览器,在上述步骤的基础上,通过以下步骤再将babel引入到项目中。

注:上一节中tsconfig.json的配置是将ts代码转换成了es6的语法,兼容性较差。使用Babel可以将其转换成更多浏览器可以兼容的低版本代码。

2、步骤

(1)安装依赖包:

  • npm i -D @babel/core @babel/preset-env babel-loader core-js
  • 共安装了4个包,分别是:
    • @babel/core : babel的核心工具
    • @babel/preset-env:babel的预定义环境
    • @babel-loader:babel在webpack中的加载器
    • core-js:core-js用来使老版本的浏览器支持新版ES语法

(2)修改webpack.config.js配置文件

	......
    module:{
        // 指定要加载(loader)的规则
        rules:[
            {
                // test 指定规则生效的文件(对谁进行编译--这里是以.ts结尾的文件)
                test: /\.ts$/,
                // 使用什么加载器来处理上面的文件。ts文件对应的就是 ts-loader
                use:[
                    // 加载器的执行时从后往前执行,所以把 ts-loader 放到后面。先让ts-loader将ts代码转成js,然后再用babel把新版本的js转换成旧版本的js
                    // 配置babel
                    {
                        // 指定加载器
                        loader:"babel-loader",
                        // 设置babel 要兼容的浏览器
                        options:{
                            // 设置预定义的环境
                            presets:[
                                [
                                    // 指定环境的插件
                                    "@babel/preset-env",
                                    // 配置信息
                                    {
                                        // 指定浏览器的版本
                                        targets:{
                                            "chrome": "58",
                                            "ie":"11"
                                        },
                                        // core-js的版本,在package.json中可以找到
                                        "corejs":"3",
                                        // 使用core-js的方式. "usage"表示按需加载
                                        "useBuiltIns":"usage"
                                    }
                                ]
                            ]
                        }
                    },
                       
                    'ts-loader',
                ],
                // 要排除的文件(不进行处理的文件,通常是node-modules)
                exclude: /node-modules/
            }
        ]
    },
    ......

如此一来,使用ts编译后的文件将会再次被babel处理,使得代码可以在大部分浏览器中直接使用,可以在配置选项的targets中指定要兼容的浏览器版本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值