typescript的查漏补缺

69 阅读3分钟

参考文章2022年了,我才开始学 typescript ,晚吗?(7.5k字总结) - 掘金 (juejin.cn),如果有错误,欢迎大家指出。

类型推论

如果没有明确的指定类型,那么 TypeScript 会依照类型推论的规则推断出一个类型。

ts
 代码解读
复制代码
let x = 1;
x = true; // 报错

上面的代码等价于

ts
 代码解读
复制代码
let x: number = 1;
x = true; // 报错

通过上述示例我们可以看出,我们没有给 x 指定明确类型的时候,typescript 会推断出 x 的类型是 number。

而如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:

ts
 代码解读
复制代码
let x;
x = 1; // 编译正确
x = true; // 编译正确

说明只有在声明变量赋值的时候会进行一次类型推论,后面赋值别的类型就会报错;如果一开始没有复制,则会推论成any类型,后面可以任意赋值。

类型断言

某些情况下,我们可能比typescript更加清楚的知道某个变量的类型,所以我们可能希望手动指定一个值的类型

类型断言有两种方式

  • 尖括号写法
ts
 代码解读
复制代码
let str: any = "to be or not to be";
let strLength: number = (<string>str).length;
  • as 写法
ts
 代码解读
复制代码
let str: any = "to be or not to be";
let strLength: number = (str as string).length;

非空断言

在上下文中当类型检查器无法断定类型时,可以使用缀表达式操作符 ! 进行断言操作对象是非 null 和非 undefined 的类型,即x!的值不会为 null 或 undefined

ts
 代码解读
复制代码
  let user: string | null | undefined;
  console.log(user!.toUpperCase()); // 编译正确
  console.log(user.toUpperCase()); // 错误

交叉类型

交叉类型就是跟联合类型相反,用&操作符表示,交叉类型就是两个类型必须存在

ts
 代码解读
复制代码
interface IpersonA{
  name: string,
  age: number
}
interface IpersonB {
  name: string,
  gender: string
}

let person: IpersonA & IpersonB = { 
    name: "师爷",
    age: 18,
    gender: "男"
};

person 即是 IpersonA 类型,又是 IpersonB 类型

注意:交叉类型取的多个类型的并集,但是如果key相同但是类型不同,则该key为never类型

ts
 代码解读
复制代码
interface IpersonA {
    name: string
}

interface IpersonB {
    name: number
}

function testAndFn(params: IpersonA & IpersonB) {
    console.log(params)
}

testAndFn({name: "黄老爷"}) // error TS2322: Type 'string' is not assignable to type 'never'.

类型守卫

类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。 换句话说,类型保护可以保证一个字符串是一个字符串,尽管它的值也可以是一个数值。类型保护与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值。

换句话说:类型守卫是运行时检查,确保一个值在所要类型的范围内

目前主要有四种的方式来实现类型保护:

  • 1、in 关键字
ts
 代码解读
复制代码
interface InObj1 {
    a: number,
    x: string
}
interface InObj2 {
    a: number,
    y: string
}
function isIn(arg: InObj1 | InObj2) {
    // x 在 arg 打印 x
    if ('x' in arg) console.log('x')
    // y 在 arg 打印 y
    if ('y' in arg) console.log('y')
}
isIn({a:1, x:'xxx'});
isIn({a:1, y:'yyy'});
  • 2、typeof 关键字
ts
 代码解读
复制代码
function isTypeof( val: string | number) {
  if (typeof val === "number") return 'number'
  if (typeof val === "string") return 'string'
  return '啥也不是'
}

typeof 只支持的类型:typeof 'x' === 'typeName' 和 typeof 'x' !== 'typeName',x 必须是 'number', 'string', 'boolean', 'symbol'。

  • 3、instanceof
ts
 代码解读
复制代码
function creatDate(date: Date | string){
    console.log(date)
    if(date instanceof Date){
        date.getDate()
    }else {
        return new Date(date)
    }
}
  • 4、自定义类型保护的类型谓词
ts
 代码解读
复制代码
function isNumber(num: any): num is number {
    return typeof num === 'number';
}
function isString(str: any): str is string{
    return typeof str=== 'string';
}