您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

TypeScript 类型断言

本节介绍类型断言,有使用关键字 as<> 两种方式,因后者会与JSX 语法冲突,建议统一使用 as 来进行类型断言。

TypeScript 允许你覆盖它的推断,毕竟作为开发者你比编译器更了解你写的。

类型断言主要用于当 TypeScript 推断出来类型并不满足你的需求,你需要手动指定类型。

当你把 JavaScript 迁移到 TypeScript 时,常见的问题:

const user = {}

user.nickname = 'Evan'  // Error, Property 'nickname' does not exist on type '{}'
user.admin = true       // Error, Property 'admin' does not exist on type '{}'

解释: 编译器推断 const user: {},这是没有的对象,所以你不能对其。

此时可以使用类型断言(as关键字)覆盖其类型推断:

interface User {
  nickname: string,
  admin: boolean,
  groups: number[]
}

const user = {} as User

user.nickname = 'Evan' 
user.admin = true       
user.groups = [, ]

解释:

第 7 行,这里通过 as 关键字进行类型断言,将变量 user 的类型覆盖为 User 类型。但是请注意,类型断言不要滥用,除非你完全明白你在干什么。

类型断言还可以通过 <> 来实现:

interface User {
  nickname: string,
  admin: boolean,
  groups: number[]
}

const user = <User>{} // User类型

user.nickname = 'Evan' 
user.admin = true       
user.groups = [, ]

解释:

第 7 行,使用 <User>{} 这种形式,将变量 user 强制断言为 User 类型。

但是,当你在使用 JSX 语法时,会跟 <> 形式的类型断言混淆:

let nickname = <User>Evan</User>  // 这里的 User 指向 component

所以,建议统一使用 as type 这种语法来为类型断言。

如果编译器不能够 null 或 undefined,可以使用非空断言 ! 手动。

function fixed(name: string | null): string {
  function postfix(epithet: string) {
    return name!.charAt() + '.  the ' + epithet; // name 被断言为非空
  }
  name = name || "Bob"
  return postfix("great")
}

解释:

第 2 行,postfix() 是嵌套,因为编译器无法嵌套的 null (除非是立即的表达式),所以 TypeScript 推断第 3 行的 name 可能为空。

第 5 行,而 name = name || "Bob" 这行已经明确了 name 不为空,所以可以直接给 name 断言为非空(第 3 行)。

双重断言极少有应用场景,只需要知道有这种操作即可:

interface User {
  nickname: string,
  admin: boolean,
  group: number[]
}

const user = 'Evan' as any as User

解释: 最后一行,使用 as 关键字进行了两次断言,最终变量 user 被强制转化为 User 类型。

本节介绍了几种类型断言的,需要注意:


联系我
置顶