typescript 中的 断言

🍉 类型断言

as<>都可以用来类型推断,但是尖括号格式会与 reactJSX 产生语法冲突,因此我们更推荐使用 as 语法。

 🥥 as

有些情况下 ts 并不能正确或者准确得推断类型,这个时候可能产生不必要的警告或者报错

const person = {};

person.name = 'randy'; // Error: 'name' 属性不存在于 ‘{}’
person.age = 20; // Error: 'age' 属性不存在于 ‘{}’

解决方法:添加类型断言

interface Person {
  name: string;
  age: number;
}

const person = {} as Person;

person.name = 'randy';
person.age = 20;

 🥥 <>

如果代码中使用 document.getElementByIdts 只知道这将返回某种 HTMLElement,但我们确定页面将始终具有具有给定 ID 的 HTMLCanvasElement

  • 通过上述的as断言
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
  • 通过<>断言
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");

🍉 双重断言

const a = expr as any as T;
虽然类型断言是有强制性的,但并不是万能的,因为一些情况下也会失效:

const x = "hello" as number;
// Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

先把类型断言为 any 再接着断言为你想断言的类型就能实现双重断言

const x = "hello" as any as number;

🍉 非空断言

在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符 !可以用于断言操作对象是非 null 和非undefined
类型。具体而言,x! 将从 x 值域中排除 nullundefined

先来看个示例:

function sayHello(name: string | undefined) {
  let sname: string = name; // Error
}

对于以上代码,TypeScript 编译器会提示一下错误信息:

Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.

要解决上述问题,我们可以简单加个条件判断:

function sayHello(name: string | undefined) {
  let sname: string;
  if (name) {
    sname = name;
  }
}

使用这种方案,问题是解决了。但有没有更简单的方式呢?答案是有的,就是使用 TypeScript 2.0 提供的非空断言操作符:

function sayHello(name: string | undefined) {
  let sname: string = name!;
}

🍉 确定赋值断言

使用场景:定义了变量, 没有赋值, 就使用,则会报错

 🥥 Example1

let num: number;
console.log(num); // error Variable 'num' is used before being assigned.
let num!: number;
console.log(num); // undefined

 🥥 Example2

let x: number;
initialize();

// Variable 'x' is used before being assigned.
console.log(x); // Error

function initialize() {
  x = 10;
}
let x!: number;
initialize();

console.log(x); // 10

function initialize() {
  x = 10;
}

🍉 类型守卫

类型守卫说白了就是缩小类型的范围,常用的有

  • 类型判断:typeof
  • 实例判断:instanceof
  • 属性判断:in
  • 字面量相等判断:==, ===, !=, !==

 🥥 类型判断:typeof

function test(input: string | number) {
  if (typeof input == 'string') {
    // 这里 input 的类型「收紧」为 string
  } else {
    // 这里 input 的类型「收紧」为 number
  }
}

 🥥 实例判断:instanceof

class Foo {}
class Bar {}

function test(input: Foo | Bar) {
  if (input instanceof Foo) {
    // 这里 input 的类型「收紧」为 Foo
  } else {
    // 这里 input 的类型「收紧」为 Bar
  }
}

 🥥 属性判断:in

interface Foo {
  foo: string;
}

interface Bar {
  bar: string;
}

function test(input: Foo | Bar) {
  if ('foo' in input) {
    // 这里 input 的类型「收紧」为 Foo
  } else {
    // 这里 input 的类型「收紧」为 Bar
  }
}

 🥥 字面量相等判断:==, ===, !=, !==

type Foo = 'foo' | 'bar' | 'unknown';

function test(input: Foo) {
  if (input != 'unknown') {
    // 这里 input 的类型「收紧」为 'foo' | 'bar'
  } else {
    // 这里 input 的类型「收紧」为 'unknown'
  }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值