 类型断言

as和<>都可以用来类型推断,但是尖括号格式会与 react 中 JSX 产生语法冲突,因此我们更推荐使用 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.getElementById,ts 只知道这将返回某种 HTMLElement,但我们确定页面将始终具有具有给定 ID 的 HTMLCanvasElement。

通过上述的as断言

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;

通过<>断言

const myCanvas = 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 值域中排除 null 和 undefined 。

先来看个示例:

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'

}

}

参考阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: