一、TS初体验
1.1.什么是Typescript?
1.Typescript 是JavaScript 的一个超集,支持ECMAScript 6标准。 2.Typescript 由微软开发的自由和开源的编程语言。 3.TypeScript 设计目标是开发大型应用,它可以编译成纯JavaScript,编译出来的JavaScript可以运行在任何浏览器上 4.TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
1.2. JS 与TS的区别
1. TypeScript是JavaScript 的超集,扩展了JavaScript的语法,因此现有的JavaScript代码可与TypeScript一起工作无需任何修改,TypeScript通过类型注解提供编译时的静态类型检查。 2TypeScript可处理已有的JavaScript代码,并只对其中的TypeScript代码进行编译。
1.3.搭建开发环境
1.安装VSCode
2.安装Node.js:使用命令node -v来检测node.js的版本
3.安装TypeScript编译器:npm i typescript -g
4.tsc --init 生成配置文件
5.使用tsc命令来转换TS为JS tsc 文件名
6.自动编译 tsc --watch
1.4. ts初体验
function text(msg:string) {
console.log(msg.length)
}
text("随机数")
text("嗯嗯嗯")
使用export default{}//可以避免作用域污染
二、TS基础数据类型
2.1.基础数据类型
数值类型、布尔类型、字符串类型
export default{}
// 数值型
let num:Number;
num=100
// num ="11"
num=3.14
console.log(num)
// 布尔类型
let flage:boolean;
flage=true
flage=false
// 字符串
let beauty:String;
beauty="张三";
let str=`我的律师是${beauty}`
console.log(str)
2.2.数组
数组分为:数组的基本使用、联合类型、任意类型
联合类型可以同时写多个类型的
export default{}
// 数组的基本使用
// 方式一
let beautyArr:string[];
beautyArr=["张三","李四","王五","周六"]
// beautyArr=["张三","李四","王五","周六",100]//报错
console.log(beautyArr)
// 方法二
let numArr:Array<number>;
numArr=[1,2,3,45,6]
// numArr=[1,2,3,45,6,"sss"]//报错
// 联合类型
let myBeauty:(number|string|boolean)[]
myBeauty=[12,"张三",true,10,"李四"]
console.log(myBeauty)
// 任意类型
let test:any[]
test=[12,"张三",true,10,"李四"]
2.3.元组
1.元祖类型Tuple
2. TS中的元祖类型其实就是数组类型的扩展
3.元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同
export default{}
let tup:[string,number,boolean]
tup=["张三",15,true]
// tup=["张三",true,15]//报错
// tup=["张三",15,true,"单词"]//超过长度报错
console.log(tup)
2.4. any和void
1. any表示任意类型,当我们不清楚某个值的具体类型时候我们就可以使用any
2.在TS中任何数据类型的值都可以赋值给any类型
使用场景一、变量的值会动态改变时,比如来自用户输入,任意值类型可以让这些变量跳过编译阶段的类型检查
let temp:any
temp="lksm"
temp=15
temp=true
使用场景二、 储存各种类型数据的数组时
let arr:any[]=["张三",18,true]
console.log(arr[0])
void类型
1.从某种程度上来讲,void类型与any类型相反,他表示没有任何类型
2.当一个函数没有返回值时,你通常会见到其返回值类型是void
3.在TS中只有null和undefined可以赋值个void
function text():void{
console.log("sdcscsdcsdcdscdscdscds")
console.log("sdcscsdcsdcdscdscdscds")
}
text()
// 在TS中只有null和undefined可以赋值个void
let test:void;
// test="sssc"
// test=18
// test=true
test=null
test=undefined
2.5.undefined与null
1.TS里 ,undefined与null两这都有自己的数据类型分别是undefined与null
2.和void相似,他们的本身的类型用处不是很大
export default{}
// TS里 ,undefined与null两这都有自己的数据类型分别是undefined与null
// 和void相似,他们的本身的类型用处不是很大
let x:undefined=undefined
let y:null=null
// 他不能赋值其他类型
// x="sscd"
// x=111
// y="scsdc"
// y=10
let mon:number=100;
mon=null
mon=undefined
2.6.never与object
Never类型
1.never类型表示的是那些用不存在的值的类型
2.例如:never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型
3.变量也可能是never类型,当他被永远不为真的类型保护所约束
function error(message:string):never{
throw new Error(message)
}
// error("报错")
// 推断的返回值类型为never
// function fali(){
// return error("ggg")
// }
// fali()
// 返回never的函数必须在无法到达的终点
function loop():never{
while(true){
}
}
obj类型
1.表示一个对象
2.定义了一个只能保存对象的变量
let godess:object;
// godess=true
// godess="zzhas"
// godess=18
godess={name:"暂时",age:15}
console.log(godess)
2.7.枚举
ts中的枚举类型和普通的js对象本质上没有区别,只是对于开发者来说,相较于直接使用值类型去做判断,枚举类型更易读,能够提升代码的可读性和易维护性
export default{}
enum Gender{
Male,//男
Femal//女
}
let gender:Gender;
gender=Gender.Male
console.log(gender)
// // 可以赋值数字
gender=10
2.7.1.如果手动指定了前面枚举
enum Gender{
Male=1,
Femal
}
console.log(Gender.Male)
console.log(Gender.Femal);
注意:TS中的枚举的取值,默认是从上到下从0开始递增的
1.虽然默认是从0开始递增的,但我们也可以手动的指定枚举的取值的值
2.注意点:如果手动指定了前面枚举的取值,那后面的值会根据前面的值递增
2.7.2.如果手动指定了后面枚举
注意点:如果手动指定了后面枚举的取值,那前面的不受影响
enum Gender{
Male,
Femal=20
}
console.log(Gender.Male)
console.log(Gender.Femal);
2.7.3.如果同时修改多个
我们可以同时使用多个枚举的值,如果同时修改多个,那么修改什么就是什么
enum Gender{
Male=200,
Femal=20
}
console.log(Gender.Male)
console.log(Gender.Femal);
2.7.4.根据索引取值,值取索引
enum Gender{
Male,
Femal
}
console.log(Gender.Femal)
console.log(Gender[0])
2.7.5函数赋值
根据函数的赋值更改值
const getNum=()=>200
let gender:Gender;
gender=Gender.Femal
gender=100
gender=getNum()
console.log(gender)
2.7.6.字符串枚举
字符串的枚举和数字的有区别不能直接赋值字符串和函数
enum Direction{
Up="UPa",
Dow="Dowe"
}
console.log(Direction.Up)
console.log(Direction.Dow)
console.log(Direction[0])
console.log(Direction["Dow"])
2.7.7.异构枚举
查找的时候只能是数字不能是字符串
enum Gender{
Male=1,
Femal="女"
}
console.log(Gender.Male)
console.log(Gender.Femal)
console.log(Gender[1])
console.log(Gender["女"])
// 只能是数字不能是字符串
2.8.bigint和symbol
2.8.1.bigint
bigint 数据类型是用来表示那些已经超出了 number 类型最大值的整数值,对于总是被诟病的整数溢出问题,使用了 bigint 后将完美解决
export default{}
let hun:bigint=BigInt(100);
let hun2:bigint=100n;
console.log(hun)
console.log(hun2)
注:BigInt()只有在你的json配置危机中es的版本改为2020才不会报错
2.8.2.Symbol
表示独一无二的值
let firstName=Symbol("name")
let seciondName=Symbol("name")
// console.log(firstName)
// console.log(seciondName)
if(firstName===seciondName){
console.log("我们一样")
}else{
console.log("我们不一样")//输出
}
注:虽然他们的Symbol("name")都是一样的但是他们的地址是不一样的
2.9.解构赋值
2.9.1 数组解构赋值
1.基本解构
let arr=["张三","李四"]
let [fister,name]=arr
console.log(fister)
console.log(name)
2.扩展运算符(注:rect输出的是数组)
let arr_1=["张三","李四","王五","赵六"]
let [name1,...rect]=arr_1
console.log(name1)
console.log(rect)
3.只输出自己想要的
let arr_1=["张三","李四","王五","赵六"]
let [,name,,rxt]=arr_1
console.log(name)
console.log(rxt);
2.9.2.对象的解构赋值
let obj={
uname:"张三",
age:18,
sex:"女"
}
let {uname,age,sex}=obj
console.log(uname)
console.log(age)
console.log(sex)
2.10.类型断言
语法一、<类型>值
let str="世界上最遥远的距离就是,你是if我是else,似乎一直相伴但又永远相离"
let len=(<string>str).length
console.log(len)
语法二、值 as 类型
let str="世界上最遥远的距离就是,你是if我是else,似乎一直相伴但又永远相离"
let num=(str as string).length
console.log(num);
进阶,把他们放到一个函数里面传入多个值,做判断
function typeArr(x:number|string){
// let len=(x as string).length
// console.log(len);
if(typeof x=="string"){
let len=(x as string).length
console.log(len);
}else{
console.log(x)
}
}
typeArr("世界上最遥远的距离就是,你是if我是else,似乎一直相伴但又永远相离")
typeArr(100)
2.11.type别名
2.11.1.类型别名的基本使用
type beautys="张三"|"李四"|"王五"|"赵六"
let on:beautys
// on="sac"//报错只能是beautys里面定义的
on="张三"
2.11.2.函数的使用
type myFun=(a:number,b:number)=>number//箭头函数a和b都是数字类型返回值也是数字类型
// 声明函数
let fun:myFun=(a:number,b:number)=>a+b
// 调用
console.log(fun(1,2))
2.11.3.对象的使用
// 对象
type myGooda={
uname:string,
age:number
sex:boolean
}
// 第一并使用他
let yifi:myGooda={
uname:"sss",
age:18,
sex:true
}
let {uname,age,sex}=yifi
console.log(uname)
console.log(age)
console.log(sex)
注:type起完别名之后就和使用number之类的一样使用
三、接口
3.1接口的基本使用
interface关键字
export default{}
// interface关键字
interface IfullName{
uname:string
age:number
}
let good:IfullName={
uname:"张三",
age:20
}
console.log(good.uname)
console.log(good.age)
//在函数中使用
function say({uname,age}:IfullName):void{
console.log(`我叫${uname},今年${age}岁了`)
}
say(good)
3.2可选属性和只读属性
3.2.1. 可选属性
直接加?问号就行
interface IfullName{
uname:string
sex:string
age?:number
}
let gooda:IfullName={
uname:"展示",
sex:"男"
}
3.2.2只读属性
关键字readonly
interface IInof{
readonly name:string
readonly sex:string
readonly age:number
}
let ine:IInof={
name:"王瑞利",
sex:"女",
age:60
}
注: readonly和const区别
1.最简单的判断该用readonly还是const的方法是看要把他做成为变量使用还是作为一个属性
2.作为变量使用的话是:const
3.若作为属性则使用readonly
3.3索引签名
解决参数可多可少问题
我们可以用前面学过的知识解决一下
3.3.1使用可选参数
interface IfullName{
fistrName:string
lastName:string
age?:number
}
let goddass1:IfullName={fistrName:"zhamgs",lastName:"lis",age:20}
let goddass2:IfullName={fistrName:"zhamgs",lastName:"lis"}
3.3.2.使用变量(使用变量赋值方法)
let info={fistrName:"杨",lastName:"密",age:20,song:"挨打的"}
let goddass3:IfullName=info
console.log(goddass3)
3.3.3.使用类型断言
let goddass4:IfullName=({fistrName:"杨",lastName:"密",age:20,song:"挨打的",tv:"手机号传送的"})as IfullName
console.log(goddass4)
3.3.4.索引签名
语法:[props:类型]:类型 如:[props:string]:string
interface IBeatuy{
[props:string]:string
}
let goddass5:IBeatuy={name1:"李易峰",name2:"王入力",name3:"zhangs"}
console.log(goddass5)
interface IAge{
[props:string]:number
}
let goddass6:IAge={age1:20,age2:30,age3:40}
console.log(goddass6)
配合使用
interface IMyFullName{
fistrName:string
lastName:string
[props:string]:string
}
let goddass7:IMyFullName={fistrName:"杨",lastName:"密",song:"挨打的",tv:"手机号传送的"}
let goddass8:IMyFullName={fistrName:"杨",lastName:"密",song:"挨打的"}
注:使用的时候一定要和定义的类型相同否则会报错
3.4 函数接口
export default{}
//定义函数接口
interface IMakeMoney{
(salary:number,rewary:number):number
}
let sum:IMakeMoney=function(x:number,y:number):number{
return x+y
}
let src=sum(1,2)
console.log(src)
3.5接口继承
3.5.1.单继承
// 单继承
interface IPerson{
age:number
}
interface INme extends IPerson{
name :string
}
let person:INme={
name:"zhangs",
age:20
}
3.5.2.多继承
// 多继承
interface IFatherMoney{
m1:number
}
interface IMonththerMoney{
m2:number
}
interface ISon extends IFatherMoney,IMonththerMoney{
s1:number
}
let person2:ISon={
s1:1,
m1:2,
m2:3
}
console.log(`总共${person2.s1+person2.m1+person2.m2}`)
注:1.不管是多继承还是单继承都是前面的继承后面的(前面为子后面的为父)
2.多继承被继承的用逗号隔开
3.6接口与类型别名的异同
3.6.1.相同点
1.都可以描述属性或方法
type WomanStr={
name:string
age:number
show():void
}
interface IWomanStr{
name:string
age:number
show():void
}
2.都可以有类型别名
let star1:WomanStr={
name:"展示",
age:20,
show(){
console.log("加油")
}
}
let star2:IWomanStr={
name:"lis",
age:80,
show(){
console.log("加油!!!!!!!!")
}
}
console.log(star1)
console.log(star2
注意:第二个是接口W前面有一个I
3.都可以扩展
type money1={
x1:number
}
type money2=money1&{
x2:number
}
let money:money2={
x1:50,
x2:20
}
console.log(money)
interface IStar1{
name:string
}
interface IStar2 extends IStar1{
age:number
}
let star:IStar2={
name:"范冰冰",
age:20
}
console.log(star)
3.6.2.不同点
1.type可以声明基本数据类型,联合类型,数组等
interface只能声明变量
type t1=number
type t2=string
type t3=number[]
type t4=[number|boolean]
interface s=string//报错
2.当出现使用type和interface声明同名变量时
type会直接报错
interface会进行组合
type Name={
name:string
}
type Name={
name:string
}//报错
interface IName{
name1:string
}
interface IName{
name1:string
age:number
}
let Name:IName={
name1:"zhas",
age:20
}
console.log(Name)