本文是ts系列其中一篇,是总结自己在学习和工作中使用ts的心得感想,仅作为自己复习使用,如对您有启发不胜荣幸。
类型保护
首先看下面这一段代码:
interface Bird {
fly: boolean
sing: () => {}
}
interface Dog {
fly: boolean
bark: () => {}
}
function trainAnimal(animal: Bird | Dog) {
animal.sing() // 提示错误
}
当我访问参数 animal 的时候,提示属性有哪些?答案是fly,没有sing或者bark。
像这种通过联合类型定义的一个变量,当我们访问这个变量的时候,只会提示公共的属性和方法。如果你这个时候直接访问animal.sing(),就会报错,避免这种报错就叫类型保护。
我们可以通过什么方式来做类型保护呢?
类型断言 as
function trainAnimal(animal: Bird | Dog) {
if (animal.fly) {
;(animal as Bird).sing()
} else {
;(animal as Dog).bark()
}
}
sameValue 现在是 any 类型,但是我知道它其实是个字符串类型,那么就需要强制转换
let sameValue: any = 'this is a string'
let strLength: number = (<string>sameValue).length
// 推荐使用这种语法
let strLength: number = (sameValue as string).length
只有联合类型才会出现需要类型保护的情况
in 语法
function trainAnimal1(animal: Bird | Dog) {
if ('sing' in animal) {
animal.sing()
} else {
animal.bark()
}
}
在 TypeScript 中,in 关键字主要有两种用法:一种是在类型上下文中(作为类型保护或映射类型的一部分),另一种是在运行时(检查对象中是否存在某个属性)。
在 JavaScript/TypeScript 的运行时环境中,in 操作符用于检查一个对象或其原型链上是否存在指定的属性。
const car = { make: 'Toyota', model: 'Camry' };
console.log('make' in car); // true
console.log('year' in car); // false
/ 继承的属性也会返回 true
console.log('toString' in car); // true, 因为从 Object.prototype 继承```
`Object.prototype.hasOwnProperty` 只检查对象自身的属性(不包括原型链)。
在 TypeScript 的类型系统中,in 关键字主要用于两个地方:类型保护(Type Guards)和映射类型(Mapped Types)。
在类型保护中,in 操作符可以用于缩小变量的类型范围。通过检查某个属性是否存在,TypeScript 可以推断出更具体的类型。如上面的例子。
在映射类型中,in 用于遍历联合类型中的每一个类型(通常是字符串字面量联合类型),从而创建一个新的类型。语法:
type Optional<T> = {
[P in keyof T]?: T[P];
};
interface Person {
name: string;
age: number;
}
typeof
function add(first: string | number, second: string | number) {
if (typeof first === 'string' || typeof second === 'string') {
return `${first}${second}`
} else {
return first + second
}
}
instanceof
instanceof 操作符是 JS 中的原生操作符,用来判断一个实例是不是某个构造函数创建的,或者是不是使用 es6 语法的某个类创建的。在 ts 中,使用 instanceof 操作符可以达到类型保护的效果。
class Fish {
swim() {
console.log('swim')
}
eat() {}
}
class Mouse {
miao() {
console.log('miao')
}
eat(){}
}
function getRandPet () : Fish | Mouse {
return Math.random() > 0.5 ? new Fish() : new Mouse()
}
const petName = getRandPet()
if (petName instanceof Fish) {
petName.swim()
}
if (petName instanceof Mouse) {
petName.miao()
}