blog icon indicating copy to clipboard operation
blog copied to clipboard

详解 TypeScript 中的 never 类型

Open chenxiaochun opened this issue 5 years ago • 3 comments

image

我一直对 TypeScript 中 never 类型比较迷惑,就是看字面好像明白是什么意思,但实际用的时候,如果抛出了相关的类型错误,又好像不知道怎么解决。

所以,这段时间查了一下相关资料。最后,看到 TypeScript 的官方 github issue 上有一篇引入这个特性时官方发布的说明,讲的应该是最权威、准确的。经个人理解,特此翻译一下,以方便其他同学。

never是指一个函数没有任何返回时的类型,它是一种从来不会为真的,在类型守护下的变量类型。还是没明白什么意思是吧?😳接着看下面的详细说明:

  • never是所有其它类型的子类型,它可以赋值给其它任何类型
  • 任何其它类型都不能赋值给never类型,除了它本身以外
const foo: never = 1 // Type '1' is not assignable to type 'never'.
  • 在一个没有返回类型注解的函数表达式或者箭头函数中。如果函数没有return语句或者return的就是一个never类型的表达式,并且函数由于具体的代码逻辑控制无法执行到终点,那么此函数的返回值就会被自动推断为never类型

由于never属于其它所有类型的子类型。因此,如果一个回调函数必须返回一个以上的特定类型时,我们可以认为它返回的其实就是never类型:

function test(cb: () => string) {
    let s = cb();
    return s;
}

test(() => "hello");
test(() => fail());
test(() => { throw new Error(); })

下面是一些会返回never类型的函数示例:

// 抛出异常,会导致下面的代码永远不会被执行,因此返回类型为 never
function error(message: string): never {
    throw new Error(message);
}

// 类型自动推断返回类型为 never
function fail() {
    return error("Something failed");
}

// 存在死循环,导致函数永远不会执行完毕,因此返回类型为 never
function infiniteLoop(): never {
    while (true) {
    }
}

帖子下面有人回复说never这个名称容易引起歧义,建议改成nothing。作者说他当初在起名时也考虑了很久,就是没有想到这个简洁明了的词语😀。

因此,nevervoid的区别就是,返回void类型的函数其实返回了一个包含void值。而返回never类型的函数就是什么都没有,就是nothing

参考资料

  • https://github.com/Microsoft/TypeScript/pull/8652
  • https://stackoverflow.com/questions/37910669/what-is-the-difference-between-never-and-void-in-typescript

chenxiaochun avatar Feb 18 '20 09:02 chenxiaochun

https://egghead.io/lessons/typescript-use-the-never-type-to-avoid-code-with-dead-ends-using-typescript

这个视频很直观

loveky avatar Feb 20 '20 02:02 loveky

@loveky ,我发现只有你分享的这一节课能看,想看其它章节都得再付费。这是为什么呢?难道是这一章节你已经付过费了?

image

chenxiaochun avatar Feb 21 '20 01:02 chenxiaochun

没付费,应该本来这一节就是可以无条件观看的

loveky avatar Feb 21 '20 07:02 loveky