Typescript: default export and namespace dual behavior as in Elm

1.7k views Asked by At

In Elm, we can write

import Html exposing (Html)

Then we do not need to type Html.Html, only Html suffice (unqualified) thus avoid the duplication. And we can still use Html as a namespace, e.g. Html.text (qualified).

How can we achieve this in Typescript? For example,

person.ts:

interface Person {
  name: string;
  age: number;
}

function isAdult(p: Person): boolean {
  return p.age >= 18;
}

export {
   Person,
   isAdult
};

other.ts:

import * a Person from "./person" 
//Then I want to be able to use both Person.isAdult and Person (as the interface)
1

There are 1 answers

0
halfzebra On BEST ANSWER

As of today(2.1.0) there are no ways for importing definitions from a module using the same identifier. In other words, you can not import Person interface and Person object as a namespace.

ES2015 import for namespace

Export the type and a function from the module.

// person.ts
export interface Person {
    name: string;
    age: number;
}

export function isAdult(p: Person): boolean {
    return p.age > 18;
}

Now you can use ES2015 import syntax to import everything as a single object. That will look like a namespace, but it's not a namespace from TypeScript.

// index.ts
import * as Person from './person';

let person: Person.Person = { name: 'John', age: 20 };

console.log(Person.isAdult(person);

Please don't be confused, there is a feature in TypeScript for providing namespaces but now it is obsolete, because of ES2015 import syntax.