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

问题描述 投票:0回答:1

下一个例子是试图重载命名空间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但请记住,这是我想要实现的一个过于简单的例子,因此这只是证明问题的最低限度。

typescript namespaces export overloading
1个回答
1
投票

问题是常量是值,而不是类型。要获得常量的类型,您需要使用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

© www.soinside.com 2019 - 2024. All rights reserved.