1.类型注解
常见的原始类型:string number boolean undefined null symbol
变量:类型名字
赋值的时候 如果类型不匹配 会报错
类型声明之后,不能更改类型
let str1: string;
str1 = "郑州" // 正确
// str1 = 123 // 错误
let isSelected: boolean = false
// isSelected ="s"
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
// ES6 中的二进制表示法
let binaryLiteral: number = 0b1010;
// ES6 中的八进制表示法
let octalLiteral: number = 0o744;
let notANumber: number = NaN;
let infinityNumber: number = Infinity;
void
JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数
function alertName(): void {
alert('My name is Tom');
}
2.类型推论
let str2 = "guigui"
// str2 = 11 // 初始化的时候赋值类型, TS会自己推论出 变量的类型
let isSelected2 = false
// isSelected2 = "s"
3.类型数组
// 限定数组的类型
let arr1: string[]; // 数组元素必须是纯字符串
// arr1 = ["74期","308","yzs",11] //错误写法
arr1 = ["74期", "308", "yzs"]
let arr2: Array<number>
arr2 = [2021, 2022]
4.元组
Tuple 元组中 允许存储不同的数据类型 和 python 的元组 概念一样
let tuple1: [string, number, boolean] = ["yzs", 30, true]
tuple1 = ["奥特曼", 300, false]
console.log("元组", tuple1, tuple1[0])
//元组 Array(3)
这样写推断不出来具体的 数组元素类型 只能推断出 变量是数组
let arr3 = ["上海", 2021, true]
arr3[0] = 1
// arr3 = []
console.log("arr3------------", arr3)
5.any类型 任意类型
需要一个装不确定类型的 数组
可以先简单理解为 泛型
广泛的类型 任意类型
let anyType: any;
anyType = 1
anyType = "1"
数组使用任意类型
let arrAny: any;
arrAny = [1, true, "yzs"]
arr**加粗样式**Any[0] = "1"
console.log("arrAny", arrAny)
6.void 代表函数没有返回值
// java object-c 常见的写法
function warn(): void { }
warn()
// ************ 有返回值 :字符串
function greet(): string {
return "有返回值-------"
}
console.log(greet())
//有返回值-------
7.参数
function play(test: string, scroe: number): string {
return `玩${test},分数是:${scroe}`
}
console.log("玩:", play("超级玛丽", 99))
// 玩: 玩超级玛丽,分数是:99
8.可选参数 和默认值的写法
function eat(who: string, place: string = "家", price?: string): void {
console.log(`${who}在${place},价格是:${price}`)
}
eat("yzs") //yzs在家,价格是:undefined
eat("yzs", "钓鱼台") //yzs在钓鱼台,价格是:undefined
eat("yzs", "钓鱼台", "99999") //yzs在钓鱼台,价格是:99999
9.函数重载
重载: 利用形参的类型或参数个数的不同,来区分多个函数
重载1 声明的时候,不需要函数体/{}
function testFn(cb1: () => void): void
重载2
function testFn(cb1: () => void, cb2: (v1: any, v2: any) => void): void
具体实现函数体
function testFn(cb1: () => void, cb2?: (v1: any, v2: any) => void) {
if (cb2) {
// cb2()
console.log("执行重载----2---")
} else {
cb1()
console.log("------执行重载1")
}
}
testFn(() => { }) //------执行重载1
testFn(() => { }, (v1, v2) => { }) //执行重载----2---
10.类型别名
对象类型 加上注解也没啥用, 并不能说明对象的结构
var person: object = { name: "yzs" }
// person.name = "11"
类型别名 类似接口
定义了 对象的 结构
对象约束 对对象的属性进行约束
var objType: { name: string, age: number }
类型别名的好处 :就是固定了 对象的结构
objType = {} // 错误的写法
属性的顺序无所谓, 只要有 类型结构对应的属性就可以了
正确使用:
objType = { age: 30, name: "yzs" }
用处: 可以自己定义类型
比上边安装 对象约束的形式 更常用
type Cat = { name: string, age: number }
var objType2: Cat;
// objType2 = {}
objType2 = { name: "加菲猫", age: 5 }
还可以导出 方便别人使用
数据列表 [{},{}] 新闻列表 商品列表
尤其用于 接收后台返回的数据的 时候使用
var cats: Cat[] = [{ name: "加菲猫", age: 4 }, { name: "波斯猫", age: 5 }]
11.类型扩展 联合类型
一个变量可以是多种类型
let union: string | number
union = "12345"
union = 123456
// union = {} // 错误写法
12.交叉类型
2种类型合并到一起 使用场景: 从服务器返回的列表数据 一般没有选中态 但是我们显示的时候一般会有类似选中态的标记 这个时候就需要用到
交叉类型 在服务器返回数据的基础上在添加一个类型
type First = { first: number }
type Second = { second: string }
type FirstAndSecond = First & Second
实战
- 模拟服务器返回的数据 结构
type User = { name: string, age: number }
type UserList = User & { selected: boolean }
// let serverUserList: UserList[] = [
// {name:"yzs",age:31}....]
服务期返回的数据和前端加上 选中态的 最后数据 这里是简化操作 实际上 ,我们获取服务器数据 然后通过遍历进行添加 selected 属性
2. 交叉类型 的使用
let serverUserList: UserList[] = [
{ name: "yzs", age: 31, selected: true },
{ name: "胡歌", age: 32, selected: false },
{ name: "毛不易", age: 33, selected: false },
{ name: "沈腾", age: 34, selected: false },
{ name: "派克特", age: 35, selected: false }]
13.class类的应用
class Parent {
// private 只能在本类访问 ,子类也无法访问
private _moneny = 98765453 // 私有属性 修饰符,不能在类外面访问,只有自己能用
// protected 只能在本类 或者子类里面使用
protected age = 31 // 受保护的
public tv = "智慧屏" // 在外部也能访问
// public
// 构造函数:参数 也可以使用修饰符
// 也属性成员变量 子类也能访问
constructor(public national = "china") {}
private job() {
console.log("父类私有方法")
}
public play(item: string) {
console.log("父类共有方法", item)
//父类共有方法 乒乓球
}
protected eat(food:string) {
console.log("父类受保护的方法------",food)
//父类受保护的方法------ 火龙果
}
子类可以访问 父类私有属性 做什么操作
// 存储器: 以属性的方式访问,可以添加额外的逻辑 控制读写
get set方法
get money(){
return this._moneny
}
set money(val:number){
this._moneny = val
}
}
class Child extends Parent {
constructor() {
super()
// 子类通过 变相方式 访问父类 私有属性
this.money = 12345678 // 本质是 set方法
console.log("子类访问父类-----------------私有属性:", this.money)
//结果:子类访问父类-----------------私有属性: 12345678
//get方法
// this._moneny //私有属性只能 在声明的类里面自己访问
// this.age // 可以访问父类受保护的 属性
// this.tv // 可以访问 父类 共有属性
console.log("子类可以访问父类 protected 修饰的变量", this.age)
//子类可以访问父类 protected 修饰的变量 31
console.log("子类可以访问父类 public 修饰的变量", this.tv)
//子类可以访问父类 public 修饰的变量 智慧屏
console.log("子类可以访问父类 构造函数 修饰的变量", this.national)
//子类可以访问父类 构造函数 修饰的变量 china
// this.job() 肯定不能访问 私有方法
this.play("乒乓球")
this.eat("火龙果")
}
}
let xiaoHuang = new Child()
console.log("子类", xiaoHuang.tv)
//子类 智慧屏
console.log("子类", xiaoHuang.money)
//子类 12345678
// console.log("子类",xiaoHuang.age)
// protected 只能在本类 或者子类里面使用
// console.log("子类",xiaoHuang._moneny)
// private 只能在本类访问 ,子类也无法访问
14.接口 interface
只定义结构 ,不定义实现
interface Book {
name: string,
price?: number
}
类型别名的写法
type Book{
name: string,
price: number
}
实战使用 接口
interface Book {
name: string,
price?: number
}
function shop(book: Book) {
return `书名: <${book.name}>;价格:${book.price}`
}
console.log(shop({ name: "西游记", price: 66 }))
//书名: <西游记>;价格:66
15.泛型
服务器返回数据
从字母 T 往后 都可以用作泛型
interface Result<T> {
ok: 0 | 1,
data: User,
msg: string
}
16.枚举
举例子来说 服务器返回的是 数字 比如 1 对应普通用户 2.vip1 3 vip2
enum Level {"王者","水晶","白银","青铜"}
console.log("枚举类型-------------",Level[0])
//枚举类型------------- 王者
enum UserType {admin = 7,manger = 3,noraml,headManger}
console.log("枚举类型 手动赋值",UserType[3])
//枚举类型 手动赋值 manger
console.log("枚举类型 手动赋值",UserType["noraml"])
//枚举类型 手动赋值 4
常数枚举§
常数枚举是使用 const enum 定义的枚举类型
游戏类里面用的非常多
const enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left,
Directions.Right];