typescript笔记

1.运行ts文件

有两种方法:
第一种是tsc XXX.ts,这一操作将会使当前的ts文件生成一个转译后的对应的js文件,然后使用node直接运行这个js文件就可以啦。
第二种就是安装ts-node,直接使用ts-node XXX.ts命令来运行ts文件,这种的会比较方便一些,但是原理都是一样的

2.常用的知识注解

  • 类型推断和类型注解
    类型推断是ts自己推断出来的数据类型(比如已经自定义好的一个对象,const aa={ one:‘23’, two: 34},这个时候one的类型就是string,two的类型就是number,ts自己是可以识别出来的)
    类型注解是我们自己在书写代码的时候自己为数据添加上的类型注解(比如函数需要传参的情况下,对于参数的数据类型,我们就需要手动的类型注解)
  • 类型断言
    ts在比较类型时,不会在意定义时的类型结构关系如何,只会比较最终的结构,例如:
interface Animal {
	name:string;
}
interface Cat {
	name:string;
	run():void // or run:() => void
}
// 这个时候虽然Animal和Cat在声明时并没有父子类之间的继承关系,但是ts在比较最终结构时,会自动认为:
Cat extends Animal {
	run():void // or run:() => void
}

所以:

  • 联合类型可以被断言为其中一个类型
  • 父类可以被断言为子类
  • 任何类型都可以被断言为 any
  • any 可以被断言为任何类型
  • 要使得 A 能够被断言为 B,只需要 A 兼容 B 或 B 兼容 A 即可
    其实前四种都是最后一种的特例!!

类型声明比类型断言更严格,我们最好优先使用类型声明,这也比类型断言的 as 语法更加优雅。

  • void类型
    表明一个没有指明的数据类型,数据类型为空,比如一个函数没有返回值
function test ():void{
console.log('测试函数没有返回值');
}
  • never类型
    表明一个函数永远不会执行完成的函数类型,such as:
function test ():never{
throw new Error();
console.log('测试函数无法执行完成');
}
  • 函数参数为解构的类型注解写法
function add(
{ first, second }: { first: number; second: string }
) {
return first + second
}
const totalNum = add({first:5,second:'s'})
console.log(totalNum)   //输出5s

一般来说,对于函数的类型注解,只需要写参数的类型就可以,返回值可以使用ts的类型推断来进行推断

const func = (str:string) =>{
return parseInt(str,10)
}
  • 对于类型不固定的变量可以使用 |,来实现变量的可变性声明
let temp:number|string = 23;
temp = 'abc';        //这里就不会报错了
  • 数组类型的定义
// 一个数组的每项都是number
const arrNum: number [] = [2,1,5,8];
//一个数组的项既有number也有string
const arrNumStr: (number | string) [] = ['a',1,4,'b'];
  • 类型为枚举中的特定值类型
enum specialTypeEnum {
	月交 = 'M',
    趸交 = 'SP',
	'Y' = '年交',
    'M' = '月交',
    'SP' = '趸交',
    'Q' = '季交',
    'A' = '交至X岁'
}
export const payPeriodRule = (amount: string, unit: keyof typeof specialTypeEnum) => {
	if(unit === 'SP' || amount === 'SP') {
        return specialTypeEnum.SP;
    };
}
  • 类型别名
    用于对于复杂数据类型的定义方式,使用type可以使对象的类型定义更加优雅
// ts可以使用别名,简化数据类型的定义 ts alias,代码读起来更加清晰
type User = {
name:string,
age:number
}
const objArr1:User [] =[{
name:'LiMIng',
age:18
}]
//使代码读起来更加清晰易懂

#######附注:还可以使用class这种定义类的方式来定义数据的类型######
如下:

class PersonType {
name:string;
age:number;
}
const objArr1:PersonType [] =[{
name:'LiMIng',
age:18    //这里数组里面的对象多一项或者少一项都会报错
},
new PersonType()
]
  • 接口Interface
    interface和type的作用其实差不多,都是用于定义一个通用的数据类型
    例如:
//注意以下两种写法的区别
interface Person{
	name:string
}
type Person = {
	name:string
}
const arrPerson:Person = {
	name:'abf'
}

//下面为接口interface的扩展
interface Person1 {
	name:string; //name属性一定有
	readonly school:string; //school是只读的string类型
	age?:number;   //age属性可有可无
	[propName:string]:any; // 可以拥有类型为string的其他属性
	say():string; //必有一个返回值为string的say函数
}

class student implements Person1 {
	name:'Liming';
	say() {
	return 'remale';
	}
} //类的定义也可以使用interface来进行数据类型的限制


 interface teacher extends Person1 {
 	sex:string
 }//接口的定义也可以使用其他接口的extends继承来进行数据类型的定义,这个时候teacher接口就继承了Person1接口上面对于数据类型的注解,还增加了对于sex属性的定义

上面例子中的两种其实都可以用来表示arrPerson这个对象的类型注解,但是区别在于interface只能代表一个对象的这样的数据类型,type却可以直接定义基础的数据类型,比如:
我可以使用 type Person = string; 这种形式来表示一个string类型的变量,但是interface却不可以。

另外,我们在日常的使用中,能使用interface就优先使用interface,不可以的再选择使用类型别名type,而且注意这种interface和typoe的定义在实际的ts编译为js代码的时候,不会作为逻辑代码存在于编译后的js中,只是ts帮助我们对于语法校验的工具而已

  • 元组tuple
    元组类型允许表示一个已知元素数量和类型的数组
const arrTuple:[string,number,number] = ['sd',12,89]
//上面对于数组类型的定义方式,就是元组
//它限制了数组的固定赋值方式,即数组的项数,每一项的类型都已经固定

3.类的应用

  • 类的访问类型
    类的访问类型有三种:
    public,private,protected
    1.public允许在类的内外被调用
    2.private允许在类内被调用
    3.protected允许在类内以及继承的子类中调用
    默认不写的时候,我们创建的都是public类型的属性或者方法
    例子:
class Person {
protected name:string;
sayHi () {
console.log(this.name) //不会报错,属于类内
}
}
const person1 = new Person()
person1.name = 'LIly'; //会报错,属于类外了

class Teacher extends Person {
sayBye (){
console.log(this.name); //不会报错,属于在继承的子类中使用
}
}
  • ts在类中使用constructor
    ts在对类中声明的某个属性进行初始化赋值的时候, 结合constructor可以对初始化过程进行简写,如下:
class Person {
//传统写法
	/*
	public name:string;
	constructor(value:string){
		this.name = value
	}
	*/
//ts的新简化写法
constructor(puclic name:string){}
}

const person1 = new Person('Lily')
console.log(person1.name)    //结果是Lily
  • ts在类中使用getter/setter
    在这里插入图片描述
  • 设计模式中的类的单例模式
class Demo {
  private static instanceName:Demo;
  private constructor(public name:string){
  	this.name=name;
    // console.log(this.name)
  }
  static creatInstance (name:string) { //	静态属性的声明static的用法是因为这样可以生成一个能在类上调用的方法,而并非生成的实例上面
    if (!this.instanceName){
      this.instanceName = new Demo(name);
    }
    return this.instanceName
  }
}
const demo1=Demo.creatInstance('lily1');
console.log(demo1) //输出结果====>  Demo { name: 'lily1' }
const demo2 = Demo.creatInstance('lily2');
console.log(demo2) //结果demo1和demo2打印出来是一样的结果,这样就实现了在类上进行初始化的创建的新对象都是一个一样的,只在第一次生成一个唯一的实例
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值