1、ts简介
以js为基础构建的语言,是js的超集,拓展了js并添加了类型,可以在任何支持js的平台执行。但是ts不能被js解析器直接执行,需要编译为js才能执行。
ts新加了类型,像枚举、any、接口、字面量等
Ts支持ES的新特性
Ts可以被编译成任意版本的js,方便兼容
2、ts环境搭建
- 下载安装node.js(ts无法独立运行需要node提供运行时环境,ts编译器需要node才能执行)
- 使用npm全局安装ts :npm i -g typescrip
-
tsc(测试是否安装成功)
- 创建一个ts文件
- 使用tsc对ts文件进行编译:在创建的ts文件的文件夹中打开cmd窗口——>键入tsc + ts文件名 可以编译生成该ts文件对应的js文件表示成功
3、ts的类型
1.ts在声明变量的时候定义类型,如果在声明的时候赋值了,那该变量的类型就是该值的类型
2.ts需要给函数的返回值以及参数定义类型,如果调用的时候返回值的类型或者参数的类型,个数对不上,均会报错,没有返回值的默认是void类型
3.类型分类:
number——数字类型
String——字符串类型
Boolean——布尔类型
字面量——变量类型设置为定值,以后该变量只能赋值该值
any——任意类型,也是默认类型,赋值给别的变量的时候,可改变别的变量的类型,污染别的变量,不建议使用
unknow——任意类型,可以接受任意类型的变量,赋值给别的变量的时候,但是不会改变别的变量的类型污染别的类型
void——空,没有值,一般在方法没有返回值的时候,默认的类型
object——对象类型
Arrary——数组类型
Tuple(元祖)——固定长度类型的数组
Enum(枚举)——枚举出需要的类型
交叉类型——方法同&,表示一个变量既是这个类型,又是那个类型
// & 交叉类型
let h:{name:string} & {age:number} //交叉类型,将两个对象合并为一个,缺一不可
h={name:'zhangsan',age:18}
// h={name:'李四'} 报错,缺少age属性
或类型——方法同|,表示一个变量可以是这个类型,也可以是那个类型
4、编译选项
- 设置监视ts文件变化,自动编译: tsc xxx.ts -w
- 当前文件夹中创建tsconfig.json 终端输入tsc -w 可以监视当前文件夹中ts文件的变化
- 相关配置选项(仅供参考
- )
{ // 该文件用来配置ts的编译选项 "include": [ // 指定ts编译的文件夹 "src/**/*", //该路径可以指定src文件下的所有的ts文件都可以被编译,**表示任意目录,*表示任意文件 "./*" ] , "exclude": [ // 指定哪些ts文件不被编译,一般用于node_modules "src/3.ts" ], // "extends" : "./tsconfig.base.json", // 指定继承的配置文件 "files":[ // 指定编译的文件路径,只有需要编译的文件比较少的时候才会用到 "./src/1.ts", ], "compilerOptions": { // 指定编译的配置 "target": "es3", // 指定编译的目标es版本,默认会转换成es3,可选的值有ES3,ES5,ES6,ES2015,ES2016,ES2017,ES2018,ES2019,ES2020,ESNext "module": "es6", // 指定模块化方案,默认是AMD,一般推荐设置为es6,可选的有none,amd,commonjs,system,umd,es6,es2015,esnext // "lib":[ // 指定编译时需要引入的库,一般在浏览器中运行,就不需要改配置了 // //可选值:'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom. iterable','webworker', 'webworker.importscripts', 'webworker.iterable', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asyncgenerator', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbol', 'es2020.bigint', 'es2020.promise', 'es2020.sharedmemory', 'es2020.string', 'es2020.symbol.wellknown', 'es2020.intl', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise', 'esnext.weakref'. // ] "outDir": "dist", // 指定编译后的文件存放的位置 // "outFile": "dist/common.js", // 指定编译后的文件存放的位置,如果设置了该选项,那么outDir会被忽略,同时module必须是amd或者system,此时会把编译后的js文件合并成一个js文件 "allowJs": true, // 是否允许编译js文件,默认是false "checkJs": false, // 是否按照ts的标准检查js文件中的错误,默认是false "removeComments": true, // 是否移除注释,默认是false "noEmit": false, // 不生产编译后的文件,但是已经编译了,默认是false "noEmitOnError": false, // 编译过程中有错误,不生成文件,默认是false "alwaysStrict": false, // 编译后的文件是否使用严格模式,默认是false "noImplicitAny": false, // 编译过程中是否检查隐式的any类型,默认是false "noImplicitThis": false, // 编译过程中是否检查隐式的this类型,默认是false "strictNullChecks": false, // 是否检查null和undefined的类型,默认是false "strict":false, // 开启所有严格检查,默认是false,开启后,strictNullChecks,noImplicitAny,noImplicitThis,strictBindCallApply,strictFunctionTypes,strictPropertyInitialization都可以不用设置了,一般都会打开 // "declaration": false, // 是否生成声明文件,默认是false } }
5、使用webpack打包ts代码
- 新建文件夹
- Npm init -y 生成package,json配置文件
- 安装依赖 npm i -d webpack webpack-cli typescript ts-loader
- 配置webpack.config.js,tsconfig.json,package.json打包命令
- Npm run build 运行。Dist目录下生成js表示打包成功
- 安装html-webpack-plugin 插件,自动构建html
- 安装webapck-dev-server 插件,package.json 配置start命令,运行命令,在浏览器上跑起来,并自动更新,mode要配置为development
- 安装clean-webpack-plugin 插件,清除上次打包的文件
- 设置resolve中的extensions可引入ts,js文件,没有配置,引入的文件位加后缀会报错
- 安装@babel/core @babel/preset-env babel-loader core-js 方便打包后的代码兼容不同的环境
@babel/core :babel编译器的核心包,把es6转换成es5,方便在不支持新语法的浏览器上运行
@babel/preset-env :预设环境,会根据目标环境和polyfill配置自动确定需要哪些插件,并引入相应的babel插件
babel-loader :webpack的loader,负责调用babel模块进行转译
core-js :提供了es6和polyfill的实现,以便在不支持新js特性的环境中使用
11.具体配置:
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 //禁止webpack使用箭头函数,,可以使打包的js最外层的不是箭头函数,不然在ie11上会报错
}
},
module: {//指定要加载的规则
rules: [
{
test: /\.ts$/, //匹配以ts结尾的文件
use: [
{
loader:'babel-loader',//指定的加载器
options:{ //设置bable
presets:[
[
"@babel/preset-env", //指定环境的插件
{ //配置信息
targets:{//要兼容的目标浏览器
"chrome":"88",
"ie":"11"
},
"corejs":"3",//指定core-js版本
"useBuiltIns":"usage",//使用core-js的方式 usage表示按需加载
}
]
]
}
},
'ts-loader'],
exclude: /node_modules/,
}
]
},
plugins:[ //引入配置插件
new HTMLWebpackPlugin({ //webpack自动生成html模板插件
// title:'这是一个自定义title',
template:"./src/index.html"
}),
new CleanWebpackPlugin() //清理dist文件夹,也就是上次打包的文件
],
resolve:{ //用来设置引用的模块
extensions:['.js','.ts'] //表示可以引入js,ts为结尾的文件
},
devServer:{
open:true
},
mode:"production"
}
6、面向对象编程
- 类:使用class定义一个类,里面有属性和方法,属性和方法分为实例属性方法和静态属性方法,实例属性方法必须通过实例获得,操作;静态属性方法可通过类名直接操作
- 构造函数constructor,主要是完成对象的初始化工作,会在类创建时调用,如果没写,自动提供一个无参数且方法为空的构造函数
- 继承extends:子类会通过extends继承父类的方法和属性,子类继承后可以有自己的方法和属性,当方法属性和父类相同时会覆盖父类
- Super表示当前继承的父类,在子类中可以通过super调用父类;abstract表示当前类是一个抽象类,抽象类只能被继承,不能被实例化
- 使用interface可以定义一个接口,类似于type类型声明,不同的是相同的type只能声明一个,但是interface可以声明多个,接口只能定义类的属性和方法,但是不能实现具体的值,就是只能定义类的结构;接口定义好了,可以通过implements实现接口
- 属性的封装:
Private:私有属性,只能在类的内部使用,无法在外面使用
Public:共有属性,可以在内外使用
Protected:受保护属性,只能在类和该类的子类中使用,不能在外面使用
内部属性可以通过get,set方法被外部获取,或者设置
(function (){
class Person{
private _name:string; //private 设置的是私有属性,只能在类的内部是用,无法在外面使用
public age:number; //public 设置的是公有属性,可以在类的内部和外部使用
protected sex:string; //protected 设置的是受保护属性,只能在类的内部和子类中用
constructor(_name:string,age:number,sex:string){
this._name = _name;
this.age=age
this.sex=sex
}
// public getName(){ //getName() 是一个方法,可以访问到私有属性name
// console.log(this.name);
// return this.name;
// }
// public setAge(age:number){ //setName() 是一个方法,可以访问到私有属性name ,
// if(age<=0){
// throw new Error('年龄不能为负数')
// }else{
// this.age=age
// }
// }
// ts优化的写法
get name(){
console.log(`调用了get name方法,传出了值----${this._name}`)
return this._name
}
set name(name:string){
console.log(`调用了set name方法,传入了值----${name}`)
if(name.length<3){
throw new Error('名字长度不能小于3')
}else{
this._name=name;
}
}
}
let p1 = new Person('zhangsan',18,'男');
// p1.name="lisi" //报错,因为name是私有的
// console.log(p1.getName());
// p1.setAge(-1);
//ts优化写法
p1.name="lisi"; //设置值,这里name其实是set name方法
console.log(p1.name); //获取值,这里name其实是get name方法
// console.log(p1.sex); //报错 无法获取sex属性,因为sex是受保护的,只能在父类和子类中使用
class Student extends Person{
say(){
console.log(this.sex);
}
}
let s1 = new Student('网二',18,'女');
s1.say();
console.log(s1.name);
console.log(s1.age);
// console.log(s1.sex); //报错,因为sex是受保护的,只能在父类和子类中使用
// class C{
// name:string;
// age:number;
// constructor(name:string,age:number){
// this.name=name;
// this.age=age
// }
// }
// 上面这种写法可以使用下面这种写法代替,更简洁
class C{
constructor(public name:string,public age:number){}
}
console.log(new C('张三',18));
})()
7、在定义函数或者类的类型不明确的时候,可以使用泛型,在设置具体值的时候赋予其类型
(function (){
/**
* 在定义函数或者是类的时候,如果遇到类型不明确的地方,可以使用泛型
* */
function fn<t>(a:t):t{
return a;
}
let b=fn(100); //此时传入的是number类型,所以返回值也是number类型
let c=fn<string>('100') //此时在调用的时候指定了类型string,所以返回值也是string类型
function fn2<t,k>(a:t,b:k):t{ //可以指定多个泛型
console.log(b);
return a
}
let d=fn2(1000,'2000')
interface i{
length:number
}
function fn3<t extends i>(a:t):number{ //t extends i 表示泛型t必须是i的子类
return a.length;
}
let e=fn3('123')
//泛型在类中的使用
class A<t>{
name:t;
constructor(name:t){
this.name=name
}
}
let aa=new A('名字')
let bb=new A<number>(123)
})()
标签:文件,false,ts,笔记,js,学习,编译,类型
From: https://blog.csdn.net/qq_25866271/article/details/140272429