Reputation: 12180
The next example is trying to overload the namespace N
but unfortunately the compiler complains that neither A
nor B
are exported members of it.
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);
Nonetheless running the compiled code gives the expected output of the following:
hello world
So the question obviously is: why is the compiler complaining? Is it reasonable for it to complain?
Note1: The compiler version I'm using is
3.1.1
Note2: I know that the above can be written as an
enum
however keep that in mind that this is an oversimplified example of what I'm trying to achieve and as such this is just the bare minimum which demonstrates the problem.
Upvotes: 1
Views: 94
Reputation: 250136
The problem is that the constants are values, not types. To get the type of a constant you need to use 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);
Note: The type and the namespace don't really share anything in common, they are different symbols that just happen to share the same name. There is no merging behavior (such as there would be with interfaces and classes for example)
Edit
Q:Why is the type of N.A
not string
?
A:The type of N.A is not string because you used a const
declaration. If you use a const the narrowest possible type is inferred. In this case that is the string literal type "hello".
Q: Why does type N = "hello" | "world"
work but not type N = N.A | N.B;
?
A:Typescript allows the usage of string literals as types as we saw above. But they are types. You can't use them in an expression, you can only use N
in a type annotation (ie this does nor work let a = N
). A variable on the other hand is a value. You can use it in an expression, and not in a type annotation (for example let o:N.A
is an error). To get to the variable's type you need the typeof
(so this will work: let o: typeof N.A
)
Upvotes: 1