打字稿:与 Elm 一样的默认导出和命名空间双重行为

Typescript: default export and namespace dual behavior as in Elm

在 Elm 中,我们可以这样写

import Html exposing (Html)

那我们就不用打Html.Html了,只要Html就可以了(不合格),避免了重复。我们仍然可以使用 Html 作为命名空间,例如Html.text(合格)。

我们如何在 Typescript 中实现这一点?例如,

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)

截至今天(2.1.0),无法使用相同的标识符从模块中导入定义。换句话说,您不能将 Person 接口和 Person 对象作为命名空间导入。

命名空间的 ES2015 导入

从模块中导出类型和函数。

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

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

现在您可以使用 ES2015 导入语法将所有内容作为单个对象导入。这看起来像一个命名空间,但它不是来自 TypeScript 的命名空间。

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

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

console.log(Person.isAdult(person);

请不要混淆,TypeScript 中有一个功能可以提供 namespaces 但现在它已经过时了,因为 ES2015 导入语法。