【问题标题】:TypeScript ignores optional parameter of type neverTypeScript 忽略类型为 never 的可选参数
【发布时间】:2018-02-04 09:41:37
【问题描述】:

我不希望将特定函数作为参数传递给另一个函数,但是根据 TypeScript,它是有效的,但是是吗?为什么?

代码示例如下:

function spoken(nope?: never): void {
    console.log("He has spoken.");
}

function speak(toSay: string, spoken: (arg1: string) => void): void {
    console.log("He says: " + toSay);
    spoken("He has spoken.");
}

speak("Hello world.", spoken);

因为基本上,TypeScript 说类型 string 可以分配给类型 never,因为如果没有,让我们说类型 number,TypeScript 会抱怨,因为类型 string 与类型 number 不兼容。

【问题讨论】:

  • 这里到底有什么意义?如果您不希望 spoken 函数接收参数,那么不要声明一个参数?
  • 当你说“根据 TypeScript 是有效的”时,你是什么意思?您应该打开strictNullChecks 编译器选项;你会看到你期望的错误。关闭 strictNullChecks 不是一个好主意,尤其是对于新代码(从纯 JS 迁移时暂时使用 false 是合理的)。
  • 顺便说一句,这显然与我的answer@WilcoBakker 上一个问题有关
  • @jcalz 是的,事实上,这是基于您的回答的直接后续问题。

标签: typescript types


【解决方案1】:

简答

...根据 TypeScript,它是有效的,但它是有效的吗?为什么?

是的,它是有效的,因为 TypeScript 说类型 never 可以分配给类型 string。这里是some code in typescript/play 来演示。

never的详细信息

Basic Types documentation 说:

never 类型是每个类型的子类型,并且可以分配给每个类型;但是,没有类型是 never 的子类型或可分配给 never(除了 never 本身)。

这意味着我们可以将never 分配给string,但不能将string 分配给never

let arg1: string = (null as never); // works
let arg2: never = (null as string); // fails

您的具体情况

您的speak 函数有一个名为spoken 的参数,该函数具有arg1 类型的string 参数。这里是 spoken 参数本身。

let spokenParam: (arg1: string) => void;

由于arg1string 并且stringnever 的超类型,因此以下赋值是有效的。

function spoken(nope?: never): void {
    console.log("He has spoken.");
}

spokenParam = spoken;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 2021-05-15
    • 2020-07-31
    • 2021-10-26
    • 1970-01-01
    • 2019-04-11
    相关资源
    最近更新 更多