js的大哥,Ts可以编辑成Js,可以规范化js
1.Ts就是Js的超集
2.简称为Ts
Ts与Js的区别
1.Ts是静态编程语言(以.ts结尾)
2.Js是动态编程语言(以.js结尾)
静态编程语言:代码写很长,需要校验极大的降低开发成本动态编程语言:只有运行才能进行校验,浪费时间但是代码写的很简便
为啥子要学习Ts?
1.Ts是目前前端工程师的加分项,将来Ts是前端必备技术.
2.像vue3等一些前端框架就是Ts对源码进行了重构,学会Ts有助于学习大型框架
在浏览器中运行Ts代码需要先将Ts代码转化为Js代码
1.安装Ts npm install -g typescript
2.检查Ts版本 tsc -v
3.将Ts代码编辑成Js tsc 文件名称
node环境中运行Ts代码
1.先安装 npm i ts-node --g
2.检查版本 ts-node -v
3.运行Ts文件 ts-node 文件名
4.ts-node 文件名不管用时 npm install -D tslib @types/node
Ts声明变量数据类型后会自动携带提示该数据类型所拥有的方法null与undefinend都是其他数据类型的子集当声明的变量不知道是什么数据类型时可以用any表示所有数据类型
元组元组类似于数组,只不过是元组将数组中的每一项都严格定义了数据类型元组拥有数组中所有的处理方法
函数
函数的声明
函数的调用
let fun = ():void =>{ console.log("一个辣鸡函数")}
fun();
函数传参
let fun = (a:number,b:number):void =>{console.log(a+b)}
fun(10,20);
函数的返回值
let fun = (a:number,b:number,c:boolean):number =>{return a+b}
fun(3,2,true);
function funA(a:number,b:number,c:boolean):number{return a+b}
funA(3,2,true);
接口的定义 interface接口,用来规范对象中各个属性的 鸭子概念:假如说看着一个东西像鸭子一样,像鸭子一样会游泳,会叫,那么就可以吧这个东西当做鸭子。
interface people {
name:string,
age:number,
color:string[],
work(a:number,b:number):number
}
let user:people = {
name:"是谁",
age:18,
color:["red","blue"],
work:(a,b)=>{
console.log("电弧")
}
}
在interface里面加入readonly表示该属性只能读取不能改变
例子 readonly name:string
加入?表示该属性可有可无
例子 age?:number
接口与函数
//? 表示可写可不写 可选参数
let myfun = (a:number, b:number,c?:number):number=>{
return a+b
myfun(1, 2, 3)
myfun(1, 2)
//接口结合函数使用
interface myfun1 {(a:number , b:number ) :number}
let funa:myfun1 = (a,b)=>{return a+b)}
funa(1,2)
let fun11:myfun1=(a,b)=>{return a+b}
1.联合类型
表示可能为多个数据类型 使用管道符|区分
联合数据类型只拥有这几种数据类型共有的方法
let tell:number | string;
2.类型推论
在Ts中,Ts可以根据您编写的代码推论出当前变量的数据类型
3.类型断言
当编辑器没有办法识别您的数据类型时,作为开发者我们可以将变量看做是固定的某个类型做处理
as 将...作为(这里全部转为字符串,获取字符串的长度)
let getStr = (a:string | number):number=>{
//将 a 参数看做是字符串类型
let stra = a as string;
if(stra.length){
return stra.length
}else{
let numa = a as number;
return numa.toString().length
}
}
let mynum = getStr("asdasdasdasdsa");
let mystr = getstr(100)
console.log(mynum,mystr)
4.类型守卫
使用typeof来判断数据类型
let getStrLength = (a:string|number):number=>{
if(typeof a =='string'){return a.length}else{return a.tostring().length}
}
类的使用
class myPeople {
name:string;
age :number;
//私有属性只允许在类的内容访问
private sex:boolean;
//构造器函数
constructor(name:string,age:number,sex:boolean)(
this .name = name;
this.age = age;
this.sex = sex;
}
say(msg:string):void{console.log(`${this.name}会说${msg}`)
}
}
let myuser = new myPeople("张三",18,true);
// console.log(myuser.sex)
myuser.say("helloWorld")
继承mypeople的属性
class zoom extends myPeople {
like:string;
constructor(name:string,age:number,sex:boolean,like:string){
super(name, age, sex);
this.like = like
}
}
let dog = new zoom("小花",1,true,"某过滤物品");
console.log(dog)
接口与数组的使用
interface mystu {
name:string,
age:number
}
let stuList:mystu[] = [
{
name:"张三",
age:18
}
]
let tuList:[mystu,string,string|number] = [{
name:"李四",
age:20
}"sdasd",'wewqe']
枚举
使用关键字enum来定义 enum 名称{ } 来定义 名称通常首字母大写
数字枚举默认从0开始计数,往后每次开始加一
enum Durion{
top,
right,
bottom,
left
}
console.log(Durion.top)
console.log(Durion.right)
最难的部分:泛型.ts
发现问题:当我们传入的位置类型,默认类型是any,丧失了类型的检测
无论传入任何数据类型,都可以根据传入的数据类型进行类型检测
泛型 genericity? 泛型可以看做在定义函数,接口或则类的时候,不先预定具体类型,当使用时再来指 定类型的一种特性.
普通函数的写法
function fungener(a:T):T{
return a
}
let res= fungener(true)
箭头函数的写法(箭头函数需要将泛型定义在等号右边)
function funmygener(a:T):T=>{
return a
}
let res2= funmygener(12345)
传入多个类型
let funMyT = (a:S,b:U):[S,U]=>{
return [a,b]
}
let res3 = funMyT("21321",1234)
总结:泛型看做是一个变量,传入什么数据类型泛型就是什么类型
泛型约束
发现问题:由于泛型事先不知道是哪一种类型,所以你不能随意操作它的属性或方法.
解决方法:泛型约束.(结合接口来实现泛型约束)
interface getLength{
length:number
}
//extends 继承
function myfunYs(a:T):void{
console.log(a.length)
}
myfunYs("23234234");
myfunYs([1, 2, 34]);
let dogs:getLength={
length:180
}
myfunYs(dogs)
复杂版(加入了两个方法)
interface arryAttr {
length :number,
push(a:number):void,
pop(a:number) :void
}
function arryFun(a:T):void{
a.push(1);
a.pop(2);
console.log(a.length)
}
arryFun([1,2, 3,4, 5])
let myArry:arryAttr = {
length:10,
push:(a)=>{
console.log(a)
},
pop:(a)=>{
console.log(a)
}
}
arryFun(myArry)
泛型与类和接口
//泛型在类中的使用
class mygoods{
name:T
price:F
color:U
constructor(name:T,price:F,color:u){
this.name = name
this.price = price
this.color = color
}
getAttr():T{
return this.name
}
}
let bag = new mygoods("ck",199,'red')
let attr = bag.getAttr();
console.log(attr)
class watch extends mygoods{
size:T
constructor(name:T,price:F,color:U,size:T){
super(name,price,color)
this.size = size
}
}
let mywathch = new watch("天王表",4999,"银色","xxL");
console.log(mywathch)
//接口中使用泛型
interface key{
name:T,
value:U
}
let goods:key={
name:"大小",
value:true
}
类型别名
给类型定义一个别的名字
//使用type定义类型别名
type funType = (a:string,b:number)=>void;
let fun111:funType =(a,b)=>{
console.log(a+b)
}
let fun222:funType = (x,y)=>{
console.log(x.length*y)
}
type s = string;
let str111:s ="111";
type son = string|number;
let x:son = 12345;
type color ="red"|"blue"|"pink";
let mycolor:color = "blue"
// 交叉类型
interface mychild {
name:string
}
//连接符表示向接口中添加属性
type m = mychild & {age:number,sex:string} & (like():void}
let children:m = {
name:"张三",
age:18,
sex:"男",
like(){
console.log("喜欢打篮球")
}
}
let lisi:mychild = {
name:"李四
}
内置类型
//内置类型
//日期类型
let time:Date = new Date();
let year = time.getFullYear();
let month = time.getMonth()+1;
let day = time.getDate();
console.log(`${year}/$(month}/${day}`)
//数学类型
let math:Math = Math;
let random = math.random()*10;
random = math.floor(random);
console.log(random)
//dom类型
let dom:HTMLElement = document.body;
dom.setAttribute("color","red");
dom.style.color = 'red';