1. TypeScript简介
本质:是以js为基础构建的语言。
意义:在js的基础上最大的差别是引入了类型的概念。使js从动态类型的语言变为静态类型的语言。
注意:ts可以在任何支持js的平台中运行,但是ts不可以直接被js解析器执行,所以要将ts编译为js再执行。
ts优势:增添类型,支持es6,增添es不具备的新特性,丰富的配置选项,强大的开发工具。
2 TypeScript的环境搭建
(1)安装ts
npm i -g typescript
(2)编译ts
在终端
tsc 01-helloTS.ts
将ts文件转化为js
3 TypeScript的类型声明
1.变量声明
2.变量的赋值和声明同时进行的情况
3.函数中的变量声明
function sum(a:number,b:number){
return a+b
}
console.log(sum(11,22))
//报错:类型“string”的参数不能赋给类型“number”的参数。t
console.log(sum(11,"123"))
//表示函数返回值的类型是number
function add(a:number,b:number):number{
return a+b
}
4 TypeScript中的类型
类型 | 例子 | 描述 |
---|---|---|
number | 1,2,-33 | 任意数字 |
string | “hello”,“hi” | 任意字符串 |
boolean | true,false | 布尔值 |
字面量 | 其本身 | 限制变量的值就是该字面量的值 |
any | * | 任意类型 |
unknown | * | 类型安全的any |
void | 空值(undefined) | 没有值(undefined) |
never | 没有值 | 不能是任何值 |
object | {name:‘weijiamin’} | 任意的JS对象 |
array | [1,2,3] | 任意JS数组 |
tuple | [4,5] | 元素,TS新增类型,固定长度数组 |
enum | enum(A,B) | 枚举类型,TS新增类型 |
例子
(1)字面量:
//a为字面量类型
let a:10
//报错:不能将类型“11”分配给类型“10”
a=11
let b:"mela"|"female"
b = 'mela'
b = 'female'
//报错:不能将类型“"nan"”分配给类型“"mela" | "female"”。
b = 'nan'
(2)any:任何类型
//显式的any
let d:any
d=1
d='hello'
d=[1,2]
//隐式any
//在TS中如果不指定类型就会自动判断变量的类型为any
let d1
d1=1
d1="hello"
let a:10
a=d1//没有报错
(3)unknown
unknown:未知类型,实质是一个类型安全的any
和any的区别?unknown类型的数据不可以赋值给其他类型的变量
// unknown
let e:unknown
e=1
e="hello"
e=[1,2]
方法1
// unknown
let e:unknown
e=1
e="hello"
let e2:string
//进行类型判断 类型相同才赋值
if(typeof e === "string"){
e2=e
}
// unknown
let e:unknown
e=1
e="hello"
let e2:string
//类型断言
e2=e as string
或者
e2=<string>e
(4)void
//void表示为空,以函数为例,表示没有返回值
//可以取undefined null
function metod1():void{
return undefined
}
(5)never
//never表示永远不会返回结果
function method2():never{
throw new Error('报错了')
}
JS中一切皆为对象
//object
let a:object
a={}
a=function (){}
//可选属性
let b1:{name:string,age?:number}
b1={name:'wei',age:11}
b1={name:'wei'}
要点1 设置对象结构的类型声明
可以添加指定属性以外的其他属性:
//添加其他属性
let b2:{name:string,[propName:string]:any}
b2={name:'wei',age:18,sex:"男"}
要点2 设置函数结构的类型声明
扩展 设置函数结构的类型声明
·
语法:(形参:类型,形参:类型)=>返回值类型
·
let b3:(a:number,b:number)=>number;
(7)array
要点3 设置数组结构的类型声明
方式1
//表示希望e是字符串类型的数组
let e:string[]
e=['1','2']
方式2
//表示希望e是数字类型的数组
let e2:Array<number>
e2=[1,2]
//定义了长度为2的字符串数组
let h:[string,string]
h=['1','2']
// h=['1']//报错
// h=['1','2','3']//报错
//定义枚举
enum Gender{
male=0,
female=1
}
let i:{name:string,gender:Gender}
i={
name:'lihua',
gender:Gender.male
}
扩展
(1)| (或)
let c:number | string
(2)& (且)
let j:{name:string}&{age:number}
j={name:'li',age:18}
(3)类型别名
type myType = string
let m:myType
type myType2 = 1|2|3|4|5
let m2:myType
let m3:myType
4 类型断言
// unknown
let e:unknown
e=1
e="hello"
let e2:string
//类型断言
e2=e as string
或者
e2=<string>e
5 TypeScript编译选项
tsc app.ts -w
不开启监视模式
开启监视模式
6 tsconfig.json配置选项(1)
"include": [
//只编译src下的任意目录的任意文件:只编译src下的所有文件
"./src/**/*"
]
用于指定哪些ts文件不被编译
默认值:[“node_modules”,“bower_components”,“jspm_packages”]
"exclude": [
//除了src/hello目录下的文件不编译,其他的文件都编译
"./src/hello/**/*/"
]
(3)extends(一般不用)
(4)files(一般不用)
"files": [
"typse.ts",
"hello.ts",
"binder.ts"
]
7 tsconfig.json配置选项(2)
编译器的选项,决定了编译器如何对ts文件进行编译
"compilerOptions": {
//用于指定ts被编译为的ES的版本
"target": "ES6",
// module 指定要使用的模块化的规范
"module": "ES6",
//lib:用于指定项目中需要使用的库 【一般不用配置】
// "lib": [],
//outDir 指定编译后文件所在的目录
"outDir":"./dist",
// 将编译后的文件合并到一个文件中 【一般不用配置】
// "outFile": "./dist/app.js"
//所有严格检查的总开关 【建议为true】
"strict": false,
//是否对js文件进行编译 默认为fasle
"allowJs": false,
//是否检查js代码是否符合ts语法的规范 默认为false
"checkJs": false,
//是否移除注释 默认为false
"removeComments": false,
//不生成编译后的文件 默认为fasle
"noEmit": false,
//当有错误的时候不生成编译后的文件 默认为fasle
"noEmitOnError": false,
// 用来设置编译后的文件是否使用严格模式
// 当有模块化代码的时候 js自动进入严格模式
"alwaysStrict": true,
//不允许隐式的any类型
"noImplicitAny": true,
//不允许不明确类型的this
"noImplicitThis": true,
//严格的检查空值
"strictNullChecks": true,
},
8 webpack打包ts文件(1)
npm init
npm i webpack-cli -g
npm i webpack-cli -D
npm i -g typescript
npm i ts-loader
//引入一个包
const path = require('path')
//webpack的配置信息
module.exports = {
//入口文件
entry:'./src/index.ts',
//打包完成后放在哪里
output:{
path:path.resolve(__dirname,'dist'),
//打包后文件名
filename:"build.js"
},
//指定webpack打包时使用的模块
module:{
//指定要加载的规则
rules:[
{
//指定规则生效的文件
test:/.ts$/,
//要使用的loader
use:'ts-loader',
exclude:/node-modules/
}
]
}
}
// tsconfig.json是ts编译器的配置文件,ts编译器可以根据它的信息来对代码进行编译
{
"compilerOptions": {
"target": "ES2015",
"module": "ES2015",
"strict": true
},
}
8 webpack打包ts文件(2)
npm i html-webpack-plugin -D
//引入html插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins:[
new HtmlWebpackPlugin({
template:'./src/index.html'
}),
]
npm i webpack-dev-server -D
修改package.json
(3)在webpack打包前先删除之前的包
npm i clean-webpack-plugin -D
//引入clean插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins:[
new CleanWebpackPlugin()
]
8 webpack打包ts文件(3)
npm i @babel/core @babel/preset-env babel-loader core-js -D
rules:[
{
//指定规则生效的文件
test:/.ts$/,
//要使用的loader
use:[
//配置babel
{
//指定加载器
loader:'babel-loader',
//设置babel
options:{
//设置预定义的环境
presets:[
[
//指定环境插件
"babel/preset-env",
//配置信息
{
//要兼容的目标浏览器
targets:{
"chrome":"88"
},
//指定corejs的版本
"corejs":"3",
//使用corejs的方式 "usage":按需加载
"useBuiltIns":"usage"
}
]
]
}
},
'ts-loader',
],
exclude:/node-modules/
}
9 面向对象
9-1 类
(1)类
class Person{
}
const per=new Person()
console.log(per)
(2)类的属性
名称 | 描述 | 例子 |
---|---|---|
实例属性 | 直接定义的属性,通过实例对象访问。可读可写 | name:string=‘wei’ |
静态属性 (类属性) | 无需创建实例对象,直接通过类访问。可读可写 | static staticAge:number |
只读属性(ts特有) | 直接定义的属性,通过实例对象访问。只读 | readonly sex:string=“nv” |
静态只读属性(ts特有) | 无需创建实例对象,直接通过类访问。只读 | static readonly staticAge:number |
//定义属性
class Person2{
//类的实例属性
name:string='wei'
age:number=18
//类的静态属性
static staticAge:number=5
//只读属性
readonly sex:string="nv"
//静态只读属性
static readonly staticName:Person = 'liu'
}
const per2=new Person2()
console.log(per2)
//访问类的实例属性
console.log(per2.age)
//访问类的静态属性
console.log(Person2.staticAge)
(3)类的方法
//定义方法
class Person3{
//定义实例方法
sayhello(){
console.log('hello')
}
//定义类方法
static sayhello(){
console.log('static hello')
}
}
const per3=new Person3()
per3.sayhello()
Person3.sayhello()
9-2 构造函数和this
this:表示当前的实例
class Dog{
name: string;
age: number;
//构造函数:在对象创建的时候调用
constructor(name:string,age:number){
//this:表示当前的实例
this.name=name;
this.age=age;
}
brak(){
console.log(this.name+'汪汪汪')
}
}
const dog = new Dog('xiaohei',4)
console.log(dog)
dog.brak()
9-3 继承
class Personn{
name: string;
age: number;
constructor(name:string,age:number){
this.name=name
this.age=age
}
sayHello(){
console.log(this.name+'hi')
}
}
const per11=new Personn('lihua',18)
per11.sayHello()
//继承Person类
//使用继承后子类将会具有父类的所有属性和方法
class Student extends Personn{
score:number
constructor(name:string,age:number,score:number){
//在子类中写了构造函数相当于覆盖了父类的构造函数,此时就要在子类的构造函数中调用父类的构造函数
super(name,age);
//新增的属性
this.score=score
}
//新增的方法
showScore(){
console.log('我的成绩是'+this.score)
}
showName(){
//在类的方法中super就相当于是当前类的父类
super.sayHello()
}
}
const student1=new Student('lihua',18,80)
student1.showScore()
//调用父类的方法
student1.sayHello()
9-4 抽象类
abstract class Personn11{
name: string;
age: number;
constructor(name:string,age:number){
this.name=name
this.age=age
}
sayHello(){
console.log(this.name+'hi')
}
}
abstract class Personn11{
name: string;
age: number;
constructor(name:string,age:number){
this.name=name
this.age=age
}
sayHello():void{
console.log(this.name+'hi')
}
abstract sayAge():void;
}
class Student11 extends Personn11{
//重写抽象方法
sayAge(){
console.log(111)
}
}
9-5 接口
接口:
1.用于定义一个类的结构应该包含哪些属性和方法,同时接口也可以当做类型声明来使用
2.接口可以重复声明,相当于在之前的类型声明基础上增加属性
3 注意: 接口中所有的属性在定义的时候都不可以有实际的值
//描述一个对象的类型
type myType = {
name:string,
age:number
}
/*
接口:用于定义一个类的结构应该包含哪些属性和方法
同时接口也可以当做类型声明来使用
*/
interface myInterFace{
name:string,
age:number,
}
//接口可以重复声明,相当于在之前的类型声明基础上增加属性
interface myInterFace{
sex:string,
//接口中所有的属性在定义的时候都不可以有实际的值
sayHello():void;
}
const obj:myInterFace={
name:'lihua',
age:111,
sex:'male',
sayHello(){
console.log('hello')
}
}
interface myInter{
name:string,
sayHello():void;
}
class MyClass implements myInter{
name: string;
constructor(name){
this.name=name
}
sayHello(){
console.log('大家好')
}
}
9-6 属性的封装
//定义一个表示人的类
class Person{
name:string;
age:number;
constructor(name,age){
this.name=name;
this.age=age
}
}
const pre = new Person('xiaozhang',18)
console.log(pre)
/*
现在的属性是在对象中设置的,属性可以任意被修改,会出现安全问题
*/
pre.age = 22
TS可以在属性前加上属性的修饰符
* public :公共的,共有的,可以在任意位置修改【默认值】
* private :私有的,只能在类内部进行访问,修改
* protected :受保护的属性,只能在当前类和其子类中使用
class Person2{
private _name:string;
private _age:number;
constructor(name,age){
this._name=name;
this._age=age
}
}
const pre2 = new Person2('xiaozhang',18)
console.log(pre)
pre2.age = 22//报错
class Person2{
private _name:string;
private _age:number;
constructor(name,age){
this._name=name;
this._age=age
}
//定义一个方法用于获取name属性
getName(){
return this._name
}
}
const pre2 = new Person2('xiaozhang',18)
console.log(pre2.getName())
class Person2{
private _name:string;
private _age:number;
constructor(name,age){
this._name=name;
this._age=age
}
//定义一个方法用于修改name属性
setName(value:string):void{
this._name=value
}
//定义一个修改年龄的方法
setAge(value:number):void{
if(value >=0 && value<=120){
this._age=value
}else{
alert('输入年龄错误')
}
}
}
const pre2 = new Person2('xiaozhang',18)
per2.setName('lihua')
getter方法用于读取方法
setter方法用于存储方法
称为属性的【存取器】
class Person2{
private _name:string;
private _age:number;
constructor(name,age){
this._name=name;
this._age=age
}
//存储器方法get 获取属性
get name(){
return this._name
}
//存储器方法set 设置属性
set name(value:string){
this._name=value
}
}
const pre2 = new Person2('xiaozhang',18)
//调用存储器方法获取name
console.log(per2.name)
//调用存储器方法设置name
pre2.name='lihua'
可以直接将属性定义在构造函数中
class Person2{
constructor(private _name:string,private _age:number){
this._name=_name;
this._age=_age;
}
}
9-7 泛型
1.定义泛型
function fn2<T>(a:T):T{
return a
}
fn2(10);不指定泛型 ts进行自动推断
fn2<string>('hello')指定泛型
3.同时定义多个泛型
function fn3<T,K>(a:T,b:K):T{
console.log(b)
return a
}
fn3(123,456)
fn3<number,string>(123,'456')
3.在函数中使用泛型
interface Inter{
length:number;
}
function fn4<T extends Inter>(a:T):number{
return a.length;
}
fn4({length:15})
4.在类中使用泛型
class MyClass<T>{
name:T;
constructor(name:T){
this.name=name
}
}
const myclass=new MyClass<string>('lihua')
10 TS开发练习
TS思想:任何东西都要写在类中
原文地址:https://blog.csdn.net/m0_56079094/article/details/124709626
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_28744.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!