声明变量的写法
安装
npm i -g typescript
文件名以ts结尾,如果语法不对,编译器会报错
typescript中数据类型有number,string,boolean,字面量,any,unknown,void,never,object,array,tuple,enum等
声明变量
可以直接在变量后添加冒号注明类型,如果未注明且未赋值,类型默认为any
let a:number;
let b: string;
let c:number=2;
let d='22'//number
let e;//any
let f:string|number//表示f的类型可以是string也可以是number
let g:{name:string}&{age:number}//表示g中既有name又有age,如`g={name:'mmc',age:1}`
字面量 :变量的类型为某个值的,如
let a: 10;let b:"male"|"female"如果某个变量可以是多种类型let c:boolean|string
let d;等价于let d:any;
let e:unknown
any类型变量可以赋值给任意类型变量,unknown则会报错
unknown赋值给其它类型变量时,可以写成
let a:string;let b:unknown;let c:number;
if(typeof b==='number'){
c=b
}
a=b as string
a=<string>b
声明函数
//函数声明,括号后面的类型为函数返回值的类型,
//当函数没有返回值时,为`void`,不写return,或return;return undefined;return null;
//`function fn1():never{}`表示永远没有返回值,比如里边抛出错误
function sum(a:number,b:number):number{
return a+b
}
//先声明后赋值
let a:(b:number,c:number)=>number
a=function(n1:number,n2:number):number{
return 11
}
对象声明
let a:{}
let b:{name:string}//b中必须有name并且只有name
let c:{name:string,age?:number}//c中必须有name,可能有age
let d:{name:string,[propName:string]:any}//d中必须有name,其它随意
数组声明
let a:string[]
a=['1','2']
let b:Array<number>
b=[1,2,3]
元组tuple,长度固定的数组
let a:[string,string,number]
a=['1','2',2]
枚举enum
enum Gender{
Male=0,Female=1
}
let a:{name:string,gender:Gender}
a={
name:'mc',gender:Gender.Male
}
类型别名
type mytype=1|2|3|4|5
let a:mytype
编译
单个编译tsc xxx.ts
单个持续编译tsc xxx.ts -w
编译后会生成对应的js文件,可以通过配置文件来决定生成文件的名字,目标文件夹等
或目录中新增tsconfig.json(可为空白{}),直接tsc便可编译当前目录所有ts文件,tsc -w同理.
tsconfig.json的一些配置
//**代表任意文件夹,*代表任意文件,exclude表示排除选项,不需要编译的文件,
//extends,表示要继承的配置文件,
//files表示被编译的文件列表,一般文件少时会用到
//自己使用时不需要将所有写出来
{
"include":[
"./src/**/*"
],//要编译的目录
“exclude”:[
"./src/hello/**/*"
],
"extends":"./config/base",
“files”:[
"xxx.ts","xx.ts"
],
"compilerOptions":{
//编译后的js的版本,默认ES3,ESNext表示默认最新,可以小写
"target":"ES6",
//module表示模块化的规范,es6,commonjs,none等
"module":"es6",
//lib指定项目中用到的库,一般情况不需要改,默认为dom
"lib":["dom"],
//outDir编译后的文件所在目录
"outDir":"./dist",
//outFile表示编译后合并为某个文件,module值需要为system
"outFile":"./dist/app.js",
"allowJs":false,//是否连js文件一起编译,默认false
"checkJs":false,//是否检查js语法
"removeComments":true,//是否移除注释
"noEmit":true,//不生成编译后的文件,一般用来检查语法
"noEmitOnError":true,//报错时不生成编译后的文件,没报错时正常生成
"alwaysStrict":false,//编译后的文件是否为严格模式,默认false
"noImplicitAny":true,//不允许隐式any,即必须声明类型
"noImplicThis":false,//不允许不明确的this
"strictNullChecks":true,//严格检查可能为null的变量的使用
"strict":true,//所有严格检查的开关
}
}
webpack使用
npm init -y生成package.json
cnpm i -D webpack-cli typescript ts-loader
1.编写webpack.config.js
const path=require('path')
module.exports={
mode:"development",
entry:"./src/index.ts",//入口文件
output:{
path:path.resolve(__dirname,'dist'),//指定打包后的目录
filename:"bundle.js"//打包后的文件名
},
module:{//指定打包时要使用的模块
//指定规则
rules:[
{
test:/\.ts$/,
use:'ts-loader',
exclude:/node-modules/
//表示使用ts-loader去编译以.ts结尾的文件,并且排除node-modules目录下的文件
}
]
}
}
2.创建tsconfig.json
3.在package.json中添加script命令
"build":"webpack"
然后npm run build执行打包
一些插件
cnpm i -D html-webpack-plugin
安装一个自动生成html的插件
//继续在webpack.config.js中
const HTMLWebpackPlugin=require('html-webpack-plugin`')
plugins:[//配置插件
new HTMLWebpackPlugin({
title:"网页title",
template:"./src/index.html"
//不加template则生成默认的index.html,加上的话需要自己创建index.html,打包后会以这个为模板生成index.html
}),
]
使用内置服务器
cnpm i -D webpack-dev-serve
然后在package.json中添加scripts命令
"start":"webpack serve --open"
然后使用npm start
上面打包dist时不会先删除dist文件,安装插件使每次打包前先删除dist
cnpm i -D clean-webpack-plugin
使用方法同上
const {CleanWebpackPlugin}=require('clean-webpack-plugin')
plugins:[//配置插件
new CleanWebpackPlugin(),
]
当有一个test.ts文件
如果引入时是import {test} from './test'
则需要在webpack.config.js中配置
resolve:{
//表示ts和js文件引入时可以不写后缀名,表示引用模块而不是整个文件
extensions:['.ts','.js']
}
如果要兼容一些低版本浏览器
cnpm i -D @babel/core @babel/preset-env babel-loader core-js
然后在webpack.config.js中配置rules
{
test:/\.ts$/,
//会先用后面的ts-loader编译ts文件,再用babel编译
// use:['babel-loader','ts-loader'],或者
use:[
{
loader:"babel-loader",
//进行一些babel配置
options:{
presets:[
//设置预定义的环境
//指定环境的插件
["@bable/preset-env",{
//要兼容的目标浏览器
targets:{
"chrome":"88",
//"ie":"11"
},
//指定corejs的版本
"corejs":"3",
"useBuiltIns":"usage",//使用corejs的方法,usage表示按需加载
}]
]
}
},'ts-loader'
],
exclude:/node-modules/
}
如果想要webpack兼容ie,在output里面配置
environment:{arrowFunction:false}表示编译后的代码不使用箭头函数
类
class Person{
name:string;
age:number;
constructor(name:string,age:number){//构造函数
this.name=name
this.age=age
}
// name:string="mmc"
// static age:number=19
// readonly color:string="red"
// static readonly height:string="111"
sayHellow(){//实例方法
}
static sayNo(){//类方法
}
}
const p1=new Person('mmc',2)
//实例属性p1.name,类属性Person.age
//继承
class Teacher extends Person{
// 如果子类中要写constructor,重写方法,则必须调用super() 表示调用父类构造函数
}
抽象类
抽象类,如父类不想被用来new,可以abstract
抽象类可以添加抽象方法,抽象方法没有方法体,子类必须重写抽象方法
abstract class Animal{
abstract sayHellow():void;
}
接口
接口,用来定义一个类的结构
可以重复定义,重复定义会融合,而不是覆盖
接口中所有属性都不能有值
interface doctor{
name:string;
age:number;
sayHello():void;
}
const obj:doctor={
name:'mmc',
age:23,
sayHello(){}
}
// 用类实现接口,里面的属性要满足接口的要求
class doc1 implements doctor{
name:'s'
age:1
sayHello(): void {
}
}
属性的封装
ts可以在属性前加修饰符
private私有属性只能在类中访问,实例无法访问,继承的类中也无法访问
protected可以被继承的私有属性
class move{
private speed:number
private _way:string
constructor(public name:string){
}
getSpeed(){
return this.speed
}
addSpeed(value:number){
this.speed+=value
}
get way(){
return this._way
}
set way(val){
this._way=val
}
}
const move1=new move('2')
move1.way
move1.way='www'
泛型
定义函数时遇到类型不明确时
function test<T>(a:T):T{
//表示函数参数和返回值类型相同
return a
}
test(1)
test('dd')
test<string>('ssss')//指定泛型
function test2<T,K>(a:T,b:K):T{
return a
}
interface Inter{
len:number
}
//表示泛型T需要实现Inter接口
function fn2<T extends Inter>(a:T):number{
return a.len
}