返回介绍

TypeScript Never 与 Unknown

发布于 2020-06-05 15:08:24 字数 3307 浏览 1634 评论 0 收藏 0

本节介绍 never 和 unknown 类型,其中 unknown 类型作为 any 类型对应的安全类型使用起来更加安全,如果有 any 类型的使用需求,应尽量使用 unknown 类型来替代 any 类型。

1. 慕课解释

never 类型表示那些永不存在的值的类型。

unknown 类型是 any 类型对应的安全类型。

2. never 类型

never 类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是 never 的子类型或可以赋值给 never 类型(除了 never 本身之外)。 即使 any 也不可以赋值给 never。

2.1 应用场景

一个抛出异常的函数表达式,其函数返回值类型为 never:

function error(message:string): never {
  throw new Error(message)
}

同样的,不会有返回值的函数表达式,其函数返回值类型也为 never:

// 推断的返回值类型为 never
function fail(): never {
    return error("Something failed")
}

不能取得值的地方:

interface Foo {
  type: 'foo'
}

interface Bar {
  type: 'bar'
}

type All = Foo | Bar

function handleValue(val: All) {
  switch (val.type) {
    case 'foo':
      break
    case 'bar':
      break
    default:
      // 此处不能取值
      const exhaustiveCheck: never = val
      break
  }
}

代码解释: 代码中所用到的接口声明(interface)、类型别名(type)、联合类型(A | B)之后都有专门小节介绍。

3. unknown 类型

我们知道 any 无需事先执行任何类型的检查:

let value: any

value = true             // OK
value = 10               // OK
value = "Hello World"    // OK
value = []               // OK
value = {}               // OK
value = Math.random      // OK
value = null             // OK
value = undefined        // OK
value = new TypeError()  // OK
value = Symbol('name')   // OK

value.foo.bar            // OK
value.trim()             // OK
value()                  // OK
new value()              // OK
value[0][1]              // OK

在许多情况下,这太宽松了。 unknown 类型呢?

let value: unknown

value = true             // OK
value = 10               // OK
value = "Hello World"    // OK
value = []               // OK
value = {}               // OK
value = Math.random      // OK
value = null             // OK
value = undefined        // OK
value = new TypeError()  // OK
value = Symbol('name')   // OK

所有对该 value 变量的分配都被认为是类型正确的。

但是,如果尝试:

let value: unknown

let value1: unknown = value   // OK
let value2: any = value       // OK

let value3: boolean = value   // Error
let value4: number = value    // Error
let value5: string = value    // Error
let value6: object = value    // Error
let value7: any[] = value     // Error

可以看到,该 unknown 类型只能分配给 any 类型和 unknown 类型本身。

现在继续尝试:

let value: unknown

value.foo.bar  // Error
value.trim()   // Error
value()        // Error
new value()    // Error
value[0][1]    // Error

unknown 类型在被确定为某个类型之前,不能被进行诸如函数执行、实例化等操作,一定程度上对类型进行了保护。

在那些将取得任意值,但不知道具体类型的地方使用 unknown,而非 any

4. 小结

到本节为止我们介绍了 TypeScript 的各种基本类型。

TypeScript 的类型系统会对数据进行类型检查,它可以在编译阶段规避不必要的错误,并且语义化清晰,有助于代码的阅读。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文