1.基础类型
TypeScript支持与JavaScript几乎相同的数据类型
注意:1.在TypeScript中变量声明了是什么类型,它赋的值也必须和声明的类型一致,不然会报错
2.声明赋值可以同时进行,ts会自动对变量进行类型检测
3.下面赋的值会覆盖上面的值
布尔
//声明完直接赋值
let aa:boolean=true
// 声明一个变量a,同时指定它的类型为number,然后再赋值
let aa:boolean
aa=true
数值
//声明完直接赋值
let num:number=11
// 声明一个变量a,同时指定它的类型为number,然后再赋值
let num:number
num=11
字符串
//声明完直接赋值
let str:string='hellow'
// 声明一个变量a,同时指定它的类型为number,然后再赋值
let str:string
str='hellow'
undefined null
let und:unfefined=undefined
let nul:null=null
console.log(und,nul) //undefined null
ndefined和null都可以作为其他类型的子类型,把undefined和null赋值给其他类型的变量的
let num:number=undefined
let str:number=null
console.log(num,str) //undefined null
数组
定义方式
1.语法:let 变量名:数据类型[]=[值1,值2,值3]
let arr1:number[]=[1,2,3,4,5]
2.泛型的写法
语法:let 变量名:Array<数据类型>=[值1,值2,值3]
let arr2:Array<number>=[1,2,3]
注意:数组定义后,里面的数据的类型必须和定义数组的时候的类型是一致,否则会有错误提示信息
元组
在定义数组的时候,类型和数据的个数一开始就已经限定了
let arr3:[string,number,boolean]=['str',111,true]
console.log(arr3) //["str", 111, true]
注意:元组类型使用的时候,数据的类型的位置和数据的个数,应该和定义元组的时候的数据一致
枚举
enum枚举类型是对javascript标准数据类型的一个补充
如果说我们有些数据是常用的,个数也是固定的,就可以把它定义为一种单独的数据类型,叫枚举类型
enum Color{
Red,
Green,
Blue
}
//定义一个变量来接收枚举的值
//根据特定的名称得到对应的数据
let aa:Color=Color.Red
console.log(aa) //0
枚举里面的每个数据值都可以叫元素,每个元素都有自己的编号,编号默认从0开始递增
可以手动指定成员的数值,也可以全部指定
enum Color{
Red = 100,
Blue
}
let aa:Color=Color:Red
console.log(aa) //100
可以通过数值来获取它的名字
enum Color{
Red = 100,
Blue
}
let aa:Color=Color:Red
console.log(Color[100]) //Red
any
可以存储任何类型的数据,当我们不知道当前数据是什么类型,但又想把他存起来可以用any类型
let str:any=100
str='hello'
console.log(str) //hello
当一个数组中要存储多个数据,个数不确定,类型不确定,也可以使用any类型
let aa:any[]=[1,'hello',true]
console.log(aa) //[1,'hello',true]
void
从某种程度上来说,void类型与any 类型相反,它没有任何类型,当一个函数没有返回值是,通常它的返回值类型是void
在函数声明时,小括号后面使用:void,代表的是该函数没有任何返回值
function aa():void{
console.log('hello')
}
console.log(aa()) //undefined
定义void类型的变量,可以接收一个undefined的值,但意义不大
let vd:void=undefined
console.log(vd) //undefined
object
function aa(obj:object):object{
return obj
}
console.log(aa({name:'张三'})) //{name: "张三"}
联合类型
表示取值可以为多种类型中的一种,一般情况下放在函数中使用
function aa(str:number|string):string{
return str.toString()
}
console.log(111) //111
console.log('111') //111
类型断言
类型断言好比类型转换,但是不进行特殊的数据检查和解构,它没有运行时的影响,只是在编译阶段
function aa(str:number|string):number{
return str.toString()
}
上面代码,如果str是string类型的话就不需要用toString()方法,这就可以用类型断言
方式一:<类型>变量名
function aa(str:number|string):number{
if((<string>str).length){
return (<string>str).length
}else{
return str.toString().length
}
}
方式二:值 as 类型
function aa(str:number|string):number{
if((str as string).length){
return (str as string).length
}else{
return str.toString().length
}
}
类型推断
ts会在没有明确的指定类型的时候推测出一个类型
let aa; //any类型
aa=10
console.log(aa) //10
下面这种情况编译器会报错
let aa='hello' //string类型
aa=10
console.log(aa)
2.接口
接口是对象的状态(属性)和行为(方法)的抽象(描述)
接口:是一种类型,是一种规范,是一种规则,是一个能力,是一种约束
定义一个接口,限定或约束对象的属性数据
interface aa{
id:number
name:string
age:number
sex:string
}
定义一个对象
注意:如果对象里的属性和接口规定的不一致,会提示类型错误
const person:aa={
id:1,
name:'张三',
age:18,
sex:'男'
}
console.log(person) //{id: 1, name: "张三", age: 18, sex: "男"}
只读属性
一些对象在创建的时候就确定了值,不能修改,在属性名前加 readonly
设置id为只读属性
interface aa{
readonly id:number
name:string
age:number
sex:string
}
可选属性
接口里的属性不全是必要的,是可有可无的,在属性名后加 ?
设置sex为可选属性
interface aa{
readonly id:number
name:string
age:number
sex?:string
}
可选属性的好处
1.可以对存在的属性进行预定义
2.可以捕获引用了不存在的属性时的错误
函数类型
通过接口的方式作为函数的类型来使用
//接口
interface aa{
(a:string,b:string):boolean
}
const bb:aa=function(a:string,b:string):boolean{
在a中查找b
return a.search(b) >-1
}
console.log(bb('hello','h')) //true
类类型
类的类型,类的类型可以通过接口来实现
类实现接口
我们可以让类实现某个接口,可以把接口看做这个类的类型
//接口
interface aa{
//是一个方法,方法中什么也没有
bb()
}
//类 Person和aa的关系是继承是实现
class Person implements aa{
//实现接口中的方法
bb(){
console.log('hello')
}
}
//实例化
const person=new Person()
person.bb() //hello
一个类可以实现多个接口
//接口
interface oo{
dd()
}
//类
class Person2 implements aa,oo{
//实现接口中的方法
bb(){
console.log('aa中的bb方法')
}
dd(){
console.log('oo接口中的dd方法')
}
}
//实例化
const person2=new Person2()
person2.bb() //aa中的bb方法
person2.dd() //oo接口中的dd方法
接口可以继承接口
//接口继承
interface cc extends aa{}
//类
class Person3 implements cc{
bb(){
console.log('cc接口中的bb方法')
}
}
//实例化
const person3=new Person3()
person3.bb() //cc接口中的bb方法
总结:
类可以通过接口的方式,来定义这个类的类型
类可以实现一个接口,也可以实现多个接口,要注意,接口中的内容都要真正的实现
接口和接口直接叫继承,类和接口直接叫实现
3.类
类可以理解为模板,通过模板可以实例化对象
面向对象的编程思想
//ts类中的定义和使用
class aa{
//定义属性
name:string
age:number
sex:string
//定义构造函数
constructor(name:string='张三',age:number=18,sex:string='男'){
this.name=name
this.age=age
this.sex=sex
}
//定义实例方法
bb(){
console.log(`我是${this.name},今年${this.age}岁,性别${this.sex}`)
}
}
//实例化对象
const cc=new aa()
cc.bb() //我是张三,今年18岁,性别男
继承
继承:类与类之间的关系
继承后类与类之间的叫法:
a类继承b类,a类叫子类,b叫基类
子类—派生类
基类—超类(父类)
定义一个类,作为基类
//定义一个类,作为基类
class fu{
//定义属性
name:string
age:number
//定义构造函数
constructor(name:string,age:number){
//更新属性
this.name=name
this.age=age
}
//定义实例方法
aa(){
console.log(`我是${this.name},今年${this.age}`)
}
}
定义一个类,作为子类,继承
//定义一个类,作为子类
class zi extends fu{
constructor(name:string,age:number){
//调用父类中的构造函数,使用super
super(name,age)
}
//调用父类中的方法
aa(){
console.log('我是子类中的aa方法')
//调用父类中的aa方法
super.aa()
}
}
实例化
//实例化父
const person=new fu('父',11)
person.aa()
//子
const stu=new zi('子',1)
stu.aa()
总结:
类和类之间继承,使用extends
子类可以调用父类中的构造函数,使用super
子类中可以重写父类的方法
公共,私有与受保护的修饰符
修饰符(类中的成员的修饰符):主要是描述类中的成员(属性,构造函数,方法的可访问性
public
类中的成员都有自己默认的访问修饰符
public修饰符,类中成员默认的修饰符,代表的是公共的,任何位置都可以访问类中的成员
class aa{
public name:string
public constructor(name:string){
this.name=name
}
}
const b=new aa('张三')
console.log(b.name) //张三
private
private修饰符,类中的成员如果使用private来修饰,那么外部是无法访问到这个成员的
class aa{
private name:string
public constructor(name:string){
this.name=name
}
}
const b=new aa('张三')
console.log(b.name) //报错属性"name"为私有属性,只能在类"aa"中访问
子类也无法访问到
class bb extends aa{
constructor(name:string){
super(name)
}
cc(){
console.log('hello',this.name) //报错属性"name"为私有属性,只能在类"aa"中访问
}
}
protected
protected修饰符,类中的成员如果使用protected来修饰,那么外部是无法访问的,子类可以
class aa{
protected name:string
constructor(name:string){
this.name=name
}
}
class bb extends aa{
constructor(name:string){
super(name)
}
cc(){
console.log('hello',this.name)
}
}
const c=new bb('李四')
c.cc() //hello 李四
readonly
对类中的属性进行修饰后,就不能再外部修改了
构造函数中,可以对只读属性修改
class aa {
readonly name: string = 'abc'
constructor(name: string) {
this.name = name
}
cc(){
console.log(this.name)
}
}
let b = new aa('hello')
b.cc() //hello
b.name = 'yes' // error 无法分配到"name",因为它是只读属性
参数属性
readonly修饰类中的构造函数中的参数(参数属性)
构造函数中name,使用readonly修饰,name参数就叫name属性,类中有了name的属性成员,外部无法修改name属性成员的值
构造函数中的name,使用public修饰,类中就有了公共的name属性成员
构造函数中的name,使用private修饰,类中就有了私有的name属性成员
构造函数中的name,使用protected修饰,类中就有了受保护的name属性成员,只能在本类和子类中使用
存取器
让我们可以有效的控制对对象的成员的访问,通过getters和setters操作
class aa {
firstName: string //姓氏
lastName: string //名字
constructor(firstName:string,lastName:string){
this.firstName=firstName
this.lastName=lastName
}
//读取器
get fullName() {
return this.firstName + '-' + this.lastName
}
//设置器
set fullName(val) {
const names = val.split('_')
this.firstName = names[0]
this.lastName = names[1]
}
}
// 获取
const p = new aa('东方','不败')
console.log(p.fullName) //东方-不败
//设置
p.fullName='司马_相如'
console.log(p.fullName)//
静态属性
静态成员:在类中通过static修饰的属性或方法,那么静态的属性以及方法,也被称为静态成员
静态成员在使用的时候,要在属性前面加类名来访问
class aa {
name1: string = 'yes'
static name2: string = 'no'
}
const a=new aa()
console.log(a.name2) //error 属性"name2"在类型"aa中不存在
console.log(aa.name2) //no
抽象类
包含抽象方法,也可以包含实例方法,抽象类是不能被实例化,为了让子类进行实例化及实现内部的抽象方法
//定义一个抽象类
abstract class fu {
//抽象方法
abstract bb()
run() {
console.log('run()')
}
}
//定义一个子类
class zi extends fu {
bb() {
console.log(' zi bb()')
}
}
const c = new zi()
c.bb() // zi bb()
//调用抽象类中的实例方法
c.run() //run()
抽象类的作用是为了子类服务
总结:
本文介绍了TypeScript的常用语法,有基础类型,接口和类
TypeScript支持与JavaScript几乎相同的数据类型,
接口是对象的状态(属性)和行为(方法)的抽象(描述)
类可以理解为模板,通过模板可以实例化对象
TypeScript和JavaScript相似,比较简单易学,必要注意的是要严格区分大小写