这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天
any类型
原则:不推荐使用any!这会让TypeScript变为"AnyScript"(失去TS类型保护的优势)。
因为当值的类型为any时,可以对该值进行任意操作,并且不会有代码提示。但这并不意味着不可以用any
let obj: any ={x:0}
obj.bar = 100
obj()
const n: number = obj
解释:以上操作都不会有任何类型错误提示,即使可能存在错误!
应尽可能的避免使用 any 类型,除非临时使用 any 来“避免”书写很长、很复杂的类型!
其他隐式具有any类型的情况: 1、声明变量不提供类型也不提供默认值2、函数参数不加类型。
注意:因为不推荐使用 any,所以,这两种情况下都应该提供类型!
typeof操作符
众所周知,JS 中提供了 typeof 操作符,用来在JS 中获取数据的类型。
console.log(typeof"Hello world")//打印 string
实际上,TS也提供了typeof操作符:可以在类型上下文中引用变量或属性的类型(类型查询)。
使用场景:根据已有变量的值,获取该值的类型,来简化类型书写。
let p = { x: 1, y: 2 }
function formatPoint(point: { x: number; y: number })
formatPoint(p)
function formatPoint(point: typeof p)
解释:
1.使用 typeof操作符来获取变量p的类型,结果与第一种(对象字面量形式的类型)相同。
2.typeof出现在类型注解的位置(参数名称的冒号后面)所处的环境就在类型上下文(区别于JS代码)。
3.注意:typeof只能用来查询变量或属性的类型,无法查询其他形式的类型(比如,函数调用的类型)。
像这种查询函数调用的返回类型是不可以的。
TypeScript高级类型
class类
TypeScript全面支持 ES2015 中引入的 class 关键字,并为其添加了类型注解和其他语法(比如,可见性修饰符等) 。
class 基本使用,如下:
class Person{}
const p: Person
const p = new Person()
解释:
1.根据TS中的类型推论,可以知道Person类的实例对象p的类型是Person。
2.TS 中的 class,不仅提供了 class 的语法功能,也作为一种类型存在。
class Person{
age:number
gender ='男'
//gender:string ='男'
}
解释:
1. 声明成员 age,类型为 number(没有初始值)。
2. 声明成员gender,并设置初始值,此时,可省略类型注解(TS类型推论为string类型) 。
class类的构造函数
ts的类中用关键字constructor
class Person {
age: number
gender: string
constructor(age: number, gender: string) {
this. age = age
this. gender = gender
}
}
解释:
1.成员初始化(比如,age:number)后,才可以通过this.age来访问实例成员。
2.需要为构造函数指定类型注解,否则会被隐式推断为any;构造函数不需要返回值类型。
class类的普通实例方法
class Point{
x= 10
y = 10
scale(n: number): void {
this.x *= n
this.y *= n
}
}
普通实例方法的类型注解(参数和返回值)与函数用法相同。
class继承
类继承的两种方式: 1 extends (继承父类) 2 implements (实现接口)。
说明: JS中只有extends,而implements是TS提供的。
class Animal{
move(){console.log('Moving along!')}
}
class Dog extends Animal{
bark(){console.log('汪!')}
}
const dog = new Dog()
解释:
1.通过extends关键字实现继承。
2.子类 Dog 继承父类 Animal,则 Dog 的实例对象 dog 就同时具有了父类Animal和 子类 Dog 的所有属性和方法。
interface Singable{
sing():void
}
class Person implements Singable{
singC(){
console.log('你是我的小呀小苹果儿')
}
}
解释:
1.通过 implements关键字让class实现接口。
2.Person类实现接口Singable意味着,Person类中必须提供Singable接口中指定的所有方法和属性。
类成员属性的可见性
类成员可见性:可以使用TS来控制class的方法或属性对于class外的代码是否可见。
可见性修饰符包括:1 public(公有的)2 protected(受保护的)3 private(私有的)。
一、public:表示公有的、公开的,公有成员可以被任何地方访问,默认可见性。
class Animal {
public move() {
console. log(' Moving along!')
}
}
解释:
1.在类属性或方法前面添加public 关键字,来修饰该属性或方法是共有的。
2.因为public是默认可见性,所以,可以直接省略。
二、protected:表示受保护的,仅对其声明所在类和子类中(非实例对象)可见
class Animal {
protected move() { console.log('Moving along!') }
}
class Dog extends Animal {
bark() {
console.log('汪!')
this.move()
}
}
1.在类属性或方法前面添加 protected 关键字,来修饰该属性或方法是受保护的。
2.在子类的方法内部可以通过this 来访问父类中受保护的成员,但是,对实例不可见!
三、private:表示私有的,只在当前类中可见,对实例对象以及子类也是不可见的。
class Animal {
private move() { console. log(' Moving along!') }
walk() {
this. move()
}
}
1.在类属性或方法前面添加 private 关键字,来修饰该属性或方法是私有的。
2.私有的属性或方法只在当前类中可见,对子类和实例对象也都是不可见的!
class类的只读修饰符
除了可见性修饰符之外,还有一个常见修饰符就是:readonly(只读修饰符)。
readonly:表示只读,用来防止在构造函数之外对属性进行赋值。
class Person {
readonly age: number = 18
constructor(age: number) {
this. age = age
}
}
解释:
1.使用 readonly 关键字修饰该属性是只读的,注意只能修饰属性不能修饰方法。
2.注意:属性 age 后面的类型注解(比如,此处的 number)如果不加,则 age 的类型为 18(字面量类型)。
3.接口或者{}表示的对象类型,也可以使用 readonly。
如
注意:只要是 readonly 来修饰的属性,必须手动提供明确的类型