import * as Button 和 import {Button} 的区别

Difference between import * as Button and import {Button}

我是 Typescript 的新手,我正在尝试使用

导入 react-bootstrap Button

案例 1:import {Button} from 'react-bootstrap/lib/Button'

案例 2:import * as Button from 'react-bootstrap/lib/Button'

这两种方式都不会在 import 语句上抛出任何错误,但在使用 <Button bsClass="glyphicon glyphicon-new-window"></Button>

呈现此 Button 时抛出错误

情况 1 没有编译时错误但是 Button is undefined

在情况 2 中,Typescript 抛出以下编译时错误 TS2604: JSX element type 'Button' does not have any construct or call signatures.

尽管这适用于 JS import Button from 'react-bootstrap/lib/Button'。现在我无法弄清楚为什么任何方法都不起作用,这两种方法有什么区别?

这取决于从某个模块导出什么样的对象。 简而言之。假设模块 "a" 导出了一些对象:

export {
    Button: function() { some button construction code},
    Link: {}
}

如果

import {Button} from 'a'

Button 将是 function() { some button construction code}

如果

import * as Button from 'a'

Button 将是整个导出对象:

    {
        Button: function() {},
        Link: {}
    }

有关详细信息,您可以查看 documentation

假设以下是 button.ts 文件的导出:

export function Button () {}
export function Toggle () {}

案例一

使用import { Button } from 'button'会给你Button功能。

Cas 2

使用 import * as Button from 'button' 会给你一个 Object 在本地命名为 Button 的两个成员:ButtonToggle。基本上

const Button = { Button:Button, Toggle:Toggle }

您可以找到有关模块语法的更多信息 here


既然您明确询问了 TypeScript,我想您也可能 运行 陷入了为什么您不再可以 import React from ' react' 而是必须使用 * as <x> 语法的问题:

这是因为 TypeScript 遵循 ESModule 规范。 Babel(以前)在幕后为我们的开发人员做了一些魔术,基本上是 ESModules 和 CommonJS 模块之间的互操作。

Imports like import React from 'react' will try to pick up the default member in the react module. If the module is bundled with CJS this member (usually) doesn’t exist. Thus, you have to use * as React from 'react' in order to obtain the exported object containing createElement, PropTypes and so on.

Source