携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
类型兼容性
ts具有类型的兼容性 声明一个接口:需要包含一个为name的属性,那么如果class中同样存在name属性
无论说声明一个类或者对象都可以对接口进行正常使用
interface Named {
name: string;
}
class Person {
name: string;
}
let p: Named;
p = new Person();
let d:Named
d = {
name:'222'
}
联合类型解决的问题
function padLeft(value: string, padding: any) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error("Expected string or number, got '".concat(padding, "'."));
}
padLeft("Hello world", 123); // ok
padLeft("Hello world", true); // err
对于以上这个例子,我们希望padding可以是number也可以是string类型,所以在定义padding的时候使用了any类型
这样的Ts编译不会出错但是这只是我们预想的传入,如果padding传入的类型是number和string之外的其他类型,那么就会抛错,所以我们应该用联合类型来解决这个问题
function padLeft(value: string, padding: string | number) { // ... }
联合类型的另一种用法
当看到联合类型的这个写法其实有点不太懂,这里的联合不像不同的联合,其实是一种公共类型,getSmallPet中需要符合‘|’前后的俩个接口的公共函数,可以在实例pet中看出来,只用使用了公共的成员ts才不会抛错。
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(): Fish | Bird { // ... }
let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim(); // errors
类型断言的用法
遇到上面这种情况就显得类型断言更加适合 对于实例pet当类型为Fish的时候才去调用swim
let pet = getSmallPet();
if ((<Fish>pet).swim) {
(<Fish>pet).swim();
}
else {
(<Bird>pet).fly();
}
类型保护
但在日常的代码中,可能上面的情况会出现很多,我们可以用类型保护的方法统一将类型断言封装起来,通过返回一个布尔值来进行判断
fucntion isFish(pet:Fish|Bird) pet is Fish{
retrun (<Fish>).siwm !== undefined
}
return返回一个类型断言进行判断,若不为undefined,则isFish为true
if(isFish(pet)){
pet.swim()
}else{
pet.fly()
}