Typescript 返回类型void和上下文类型

Typescript 返回类型void和上下文类型,typescript,Typescript,下面的voidFunc返回void。但是,v1返回true 这是正确的吗 一切正常 正如TypeScript编译器和编写TypeScript代码的开发人员所观察到的那样,您似乎混淆了静态类型系统的行为;运行时的行为,正如JavaScript引擎和开发人员在控制台调试时所观察到的 为了突出区别,这里有三个不同的TypeScript程序,它们在运行时的行为恰好相同 我称之为“太宽”: 这个“太窄了”: 而这一个“恰到好处”: 如果编译并运行它们,您将看到相同的结果“你好!”将被记录到控制台。但它们

下面的
voidFunc
返回
void
。但是,
v1
返回
true

这是正确的吗


一切正常

正如TypeScript编译器和编写TypeScript代码的开发人员所观察到的那样,您似乎混淆了静态类型系统的行为;运行时的行为,正如JavaScript引擎和开发人员在控制台调试时所观察到的

为了突出区别,这里有三个不同的TypeScript程序,它们在运行时的行为恰好相同

我称之为“太宽”:

这个“太窄了”:

而这一个“恰到好处”:

如果编译并运行它们,您将看到相同的结果<代码>“你好!”将被记录到控制台。但它们在编译时提出了不同的声明,编译器认为只有“恰到好处”才是正确的

“太宽”表示函数
foo()
将接受
string
number
类型的任何参数。。。如果是这样的话,
foo()
的实现就是错误的,因为它试图访问一个
toUpperCase()
方法,该方法可能是一个
数字。有人可以更改程序,以便调用
foo(123)
。任何依赖于传递给
foo()
的值作为
字符串的代码都有问题

另一方面,“太窄”表示
foo()
只接受字符串
“再见!”
。。。如果是这样,调用
foo(“hello!”)
是错误的,因为不允许
“hello!”
。任何代码如果将除“再见!”
以外的内容传递给
foo()
就是做错了什么

请注意,类型越宽,提供满足它的值就越容易,但使用起来就越困难。。。另一方面,类型越窄,使用该类型的值就越容易,但提供值就越难


让我们看看返回
void
的函数。像
()=>void
这样的函数类型非常广泛。在提供这样的函数时,您有更多的自由,但在使用它时几乎没有自由。
void
返回类型表示“您不应将此函数的返回值用于任何目的。它可能返回某些内容,但您应忽略它”

例如,以下程序出错:

const f: () => void = () => true;
if (f()) { console.log("hi!") }; // error!
//  ~~~ <-- An expression of type 'void' cannot be tested for truthiness.
同样,类型为
()=>void
的函数的提供者可以自由返回他们想要的任何东西;在这种情况下,它恰好是一个
Date
对象。但不允许该函数的调用方将返回值视为
Date
对象。在运行时这样做恰好是好的,但这是一个不正确的TypeScript程序。我可以更改
g()
,使其返回我想要的任何内容,然后
g()。getFullYear()
可能在运行时和编译时都会出错


function foo(x: string | number) {
    console.log(x.toUpperCase()); // compiler error;
    // Property 'toUpperCase' does not exist on type 'number'
}
foo("hello!");
function foo(x: "goodbye!") {
    console.log(x.toUpperCase());
}
foo("hello!"); // compiler error;
// Argument of type '"hello!"' is not assignable to parameter of type '"goodbye!"'
function foo(x: string) {
    console.log(x.toUpperCase());
}
foo("hello!");
const f: () => void = () => true;
if (f()) { console.log("hi!") }; // error!
//  ~~~ <-- An expression of type 'void' cannot be tested for truthiness.
const g: () => void = () => new Date();
g().getFullYear(); // error!  Property 'getFullYear' does not exist on type 'void'