### 1.什么是TS?
TS是JS的超集,JS中有的特性都可以在TS中使用,而且可以使用ES6新特性。但是TS文件不能被JS解析器直接解析,需要通过一个编译过程:tsc <文件名> ——将一个TS文件编译成JS文件。TS的一大特点是变量具有类型。
2.TS语法
1.如何给变量指定类型?
let a:string = 'hello'
如果变量的声明和赋值是同时进行的,那么就可以自动获得这个变量的类型。比如上面的代码不写:string也是可以的。变量指定类型也可以用在函数参数上和返回值上,如下所示:
function add(a:number,b:number):number{
console.log(a+b)
return 0
}
add(12,13)
2.字面量的应用场景
//将b的值限定在这三个值的范围之内
let b: 'male' |'female' | 'secret'
console.log(b)
//将b类型限定在这三个值的范围之内
let b: boolean | string | number
console.log(b)
3.新增类型
3.1 any类型
一个变量设置类型为any后,相当于对这个变量关闭了TS的类型检测。
let a:any(显示)
相当于:let a(隐式)
3.2 unknown类型
unknown类型的变量和any类型的变量是及其相似的,都是可以接受任意类型的值,但是不同的是any类型的变量是可以赋值给其他具体类型的变量,导致其他类型的变量的类型检查也会关闭,但是unknown类型的变量是不可以赋值给其他类型变量的。所以用unknown也不用any
3.3 void类型
一般用来设置一个函数的返回值类型,表示函数没有返回值。
3.4 never类型
一般用在报错函数的返回值上,比较鸡肋。
3.5 object
如何规定一个对象中必须有什么属性?
let a:object//用的不是很多,因为对象也有好多子类型,这样写并不能具体到某一个子类型
let b: { name: string}//这就规定了b指向的对象里面有且仅有name
b = {}//报错
b = {
name:'zh'
}//不报错
//灵活添加属性
let b: {
name: string
age?: number//加了问号代表可选属性
[propName: string]: any//这样写了以后这个对象中就可以添加任何数量的任意属性
}
b = {
name:'zh',
school: 'tjut',
major: 'xxx'
}
3.6 function
如何规定一个函数的参数类型和返回值类型?
//规定有两个参数,都是number类型,返回值是string类型
let fun: (a:number,b:number)=>string
3.7 array
let e : string[]//规定数组的元素都是string类型
let e: Array<string>//和上面的效果一样
3.8 tuple
固定长度的数组
let a: [string,number]
a=["123",123]
3.9 enum
//定义一个枚举类
enum Gender{
male,
female
}
let obj:{
name:string,
//gender是Gender类型的,只有两个可选值
gender:Gender
}
obj = {
name: 'zh',
gender: Gender.male
}
export {}
4.编译选项
4.1监视单个文件,当ts文件保存时,自动编译:
tsc <文件名> -w
4.2 监视多个文件
首先创建一个tsconfig.json文件,然后tsc -w命令就可以监视所有的ts文件
4.3 tsconfig.json配置项
{
//表示那些文件需要被编译,**代表任意文件夹,*代表任意文件
"include": [
"./**/*"
],
//与include相反,有些文件不希望被编译
// "exclude": [
// "./2.ts"
// ]
//编译器选项,表示如何对ts文件进行编译
"compilerOptions": {
//编译成js文件的版本
"target": "ES3",
//模块化标准
"module": "es6",
//用来指定项目中要是用的库,一般不用设置
// "lib": []
//指定编译后的js文件的目录
"outDir": "./dist",
//将所有的ts文件的编译成的js文件合并到同一个文件中,用的不多
// "outFile": "./dist/app.js"
//是否编译js文件
"allowJs": false,
//是否检查js
"checkJs": false,
//ts文件的注释是否被转到js文件中
"removeComments": false,
//是否生成编译后的js文件
"noEmit": false,
//严格检查的总开关
"strict": true,
//ts文件有错误的时候是否生成js文件
"noEmitOnError": true,
//对编译后的js文件时候使用严格模式
"alwaysStrict": true,
//是否禁止使用隐式的any 如函数的参数的类型必须不明确指定的时候就是any
"noImplicitAny": true,
//是否禁止隐式的this
"noImplicitThis": true,
//是否检查可能为空的值
"strictNullChecks": true
}
}
4.4 webpack配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
//指定入口文件
entry: './src/index.ts',
//编译输出文件的配置
output:{
path: path.resolve(__dirname,'dist'),
filename: 'bundle.js',
//配置目标文件
environment:{
//不允许使用箭头函数
arrowFunction: false
}
},
//打包时要使用的模块
module:{
//指定加载规则
rules: [
{
test: /\.ts$/,
use: [
{
//指定加载器
loader:"babel-loader",
//配置babel
options:{
//设置预定义环境
presets: [
[
"@babel/preset-env",
{
//要兼容的目标浏览器
targets:{
"chrome":"88",
"ie":"11"
},
//指定corejs的版本
"corejs":"3",
//使用corejs的方式,按需加载
"useBuiltIns":"usage"
}
]
]
}
},
"ts-loader"
],
exclude: /node-modules/
}
]
},
plugins: [
//指定生成html文件的模板文件的位置
new HtmlWebpackPlugin(
{
template: './src/index.html'
}
),
//编译的时候首先清空dist文件夹下文件
new CleanWebpackPlugin()
],
resolve: {
//规定设么扩展名的文件可以当做一个模块来导入导出
extensions: ['.ts','.js']
}
}
5.面向对象
ts中面向对象的知识和Java中面向对象的知识相似。
5.1类
class Person{
name: string //通过对象实例去访问
readonly age: number //通过对象实例去访问 readonly表示一个只读的属性
static school: string = 'tjut' //静态属性通过类名访问
constructor (name: string,age: number){
this.name = name,
this.age = age
}
sayHello(){
console.log('hello ts')
}//静态方法和静态属性的特定是一样的
}
//new Person()调用的时候相当于调用了构造函数
const p = new Person('zh',18)
console.log(p)//Person { name: 'zh', age: 18 }
console.log(Person.school)//tjut
p.sayHello()//hello ts
5.2 继承、抽象类和接口
继承之后子类拥有父类所有的属性和方法,通过继承我们可以将多个类共有的方法抽取到一个类中。子类和父类中有相同的方法,子类中的方法会覆盖父类中的方法,这就是方法的重写。super关键字就是代表当前类的父类。用抽象类就可以避免用这个类来创建一个对象,比如Animal类,所以抽象类就是用来被继承的。抽象类中可以有抽象方法,抽象方法没有具体实现,只有结构没有方法体,子类必须对抽象方法进行重写。
和抽象类及其相似的一个东西是接口,接口用来定义一个对象中包含哪些属性和方法,也可以当成一个类型来使用。接口中的属性都不能有实际的值,而且所有的方法都是抽象方法。让一个类去实现一个接口,就是让一个类按照接口中的属性和方法类写,接口就是一种规范,对类的一种限制。抽象类中可以有非抽象方法,但是接口中只能有抽象方法。
interface Animal{
name: string
age: number
sayName(): void
}
class Dog implements Animal{
constructor (public name: string,public age: number){
}
sayName(){
console.log('hahahh')
}
sport(){
console.log('running')
}
}
const dog = new Dog('旺财',3)
dog.sport()//running
5.3属性修饰符
public 在任何地方都可以修改,这个也是默认值。private 私有只能在类内部修改。protected只能在当前类和当前类的子类中访问
5.4在定义函数或者类的时候,如遇到类型不确定的时候就可以用泛型
function fn<T>(a:T):T {
return a
}