为什么命名空间重载不起作用?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么命名空间重载不起作用?相关的知识,希望对你有一定的参考价值。

下一个例子是试图重载命名空间N但不幸的是编译器抱怨AB都不是它的导出成员。

namespace N
{
    export const A = 'hello';
    export const B = 'world';
}

type N = N.A | N.B;

const a: N = N.A;
const b: N = N.B;

console.log(a, b);

尽管如此,运行已编译的代码会产生以下预期输出:

hello world

所以问题显然是:为什么编译器会抱怨?抱怨是否合理?

注1:我使用的编译器版本是3.1.1

注意2:我知道上面的内容可以写成enum但请记住,这是我想要实现的一个过于简单的例子,因此这只是证明问题的最低限度。

答案

问题是常量是值,而不是类型。要获得常量的类型,您需要使用typeof

namespace N
{
    export const A = 'hello';
    export const B = 'world';
}

type N = typeof N.A | typeof N.B;

const a: N = N.A;
const b: N = N.B;

console.log(a, b);

注意:类型和命名空间并不真正共享任何共同点,它们是碰巧共享相同名称的不同符号。没有合并行为(例如,可能有接口和类)

编辑

问:为什么N.A的类型不是string

答:N.A的类型不是字符串,因为您使用了const声明。如果使用const,则推断出最窄的类型。在这种情况下,这是字符串文字类型“hello”。

问:为什么type N = "hello" | "world"工作但不是type N = N.A | N.B;

答:Typescript允许使用字符串文字作为我们在上面看到的类型。但他们是类型。你不能在表达式中使用它们,你只能在类型注释中使用N(即这样做也不起作用let a = N)。另一方面,变量是一个值。您可以在表达式中使用它,而不是在类型注释中使用它(例如let o:N.A是一个错误)。要获得变量的类型,您需要typeof(所以这将起作用:let o: typeof N.A

以上是关于为什么命名空间重载不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 入门超详解!

C++ 入门超详解!

C++快速入门(命名空间,输入输出,缺省函数,函数重载)

C++快速入门(命名空间,输入输出,缺省函数,函数重载)

当内部作用域不起作用时,为啥编译器不采用命名空间名称?

04. 命名空间,函数重载,内联