Repository: TypeScript
Issue:  Let type identifiers co-exist with import namespace identifiers
Labels: Suggestion,In Discussion

## Search Terms

Modules, export, import

## Suggestion

It would be convienent if type identifiers could co-exist with import namespace identifiers.

## Use Cases

A common pattern is to have a module where the module name is the same as the main type exported by that module.

## Examples

Consider this module:

**result.ts**

```ts
export type Result<TError, TValue> =
  | { readonly type: "Ok"; readonly value: TValue }
  | { readonly type: "Err"; readonly error: TError };

export function Ok<TValue>(value: TValue): Result<never, TValue> {
  return { type: "Ok", value };
}

export function Err<TError>(error: TError): Result<TError, never> {
  return { type: "Err", error };
}

// .. more functions to work with the Result type
```

Now consider a consumer of this moudule:

```ts
import * as Result from "./result";

export function itsOk(): Result.Result<string, string> {
  const ok: Result.Result<string, string> = Result.Ok("");
  const err: Result.Result<string, string> = Result.Err("");
  return ok;
}
```

There are execessive type annotations in this example but the point is that it is annoying ot have to refer to the type `Result` as `Result.Result`. I would like to refer to the type as only `Result` but still have functions related to the module in a `Result` namespace.

I was reading about the new `import type` syntax in 3.8 and thought I might get away with something like this:

```ts
import * as Result from "./result";
import type { Result } from "./result";

export function itsOk(): Result<string, string> {
    const ok: Result<string, string> = Result.Ok("")
    const err: Result<string, string> = Result.Err("")
    return ok;
}
```

This fails because there are duplicate identifiers. Typescript does allow duplicate identifiers that live either 100% in the type world or 100% in the concrete world. But imported namespace objects (`import * as`) lives in both worlds so it does not currently work. Specifically namespace object can contain both types and concrete things.

However I think typescript should be able to infer from usage if I'm referring the type or the namespace when using it in a place where types can be used. If what is referenced could be found by looking at the usage then duplicate identifiers could be allowed. I believe some other languages does it this way.

In this example the type used does not have a dot so it is referring to the imported type rather than the imported namespace.

```ts
const ok: Result<string, string> = ..
```

In this example the type used has a dot so it is referring to the namespace object.

```ts
const ok: Result.OtherType = ..
```

I think this is not related to the ECMA standard for modules and import/export but rather something typescript decide how to handle because it is fully in the "type world" which gets erased when emitted to js.

## Checklist

My suggestion meets these guidelines:

- [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [x] This wouldn't change the runtime behavior of existing JavaScript code
- [x] This could be implemented without emitting different JS based on the types of the expressions
- [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).