Миграция React ES6 на TypeScript: операторы импорта не работают

У меня есть проект React, написанный в настоящее время на ES6, который я переношу на TypeScript. У меня проблемы с операторами import.

В настоящее время с ES6 я установил зависимости React, используя NPM, ex npm install react, и использую Babel с Browserify для создания выходного пакета ES5. (Использование Browserify не является обязательным требованием, я просто пытаюсь заставить TS работать с проектом.)

Типичный файл React ES6 выглядит так:

import React from "react"
import {Router, Route, Link} from "react-router"
import Button from "./components/Button"

export default class App extends React.Component {
    render(){ 
        // ...
    }
}

Переходя к TS, я установил d.ts файлов для всех своих зависимостей React, используя tsd install react/, установил TSC module: "commonjs" и jsx: "react", преобразовал несколько файлов из *.jsx в *.tsx, и я получаю следующие ошибки компиляции в операторах import:

Ошибка: (1, 8) TS1192: модуль «реагировать» не имеет экспорта по умолчанию.

Оператор import Button не дает ошибок. Похоже, TSC не может разрешить зависимости модуля NPM.

Как я могу заставить это работать?


person Aaron Beall    schedule 19.11.2015    source источник
comment
Я сталкиваюсь с проблемой наоборот. У меня есть библиотека, построенная на TypeScript. Я сделал из него сборку и попытался импортировать файл js. Localhost:3000 у меня работает хорошо. Но когда я делаю npm run build, он говорит, что в ts-file-transpiled.js есть функция someFunc(), которая неправильно экспортируется. Я не знаю, как это сделать.   -  person sidnc86    schedule 10.06.2020


Ответы (2)


TypeScript 1.8+

Скомпилируйте с помощью --allowSyntheticDefaultImports — добавьте "allowSyntheticDefaultImports": true в tsconfig.json

Примечание: это не работает для меня, когда я устанавливаю module в tsconfig.json на commonjs.

В качестве альтернативы...

Используйте это вместо этого:

import * as React from "react";
import * as Router from "react-router";

// use React, Router.Router, Router.Route, and Router.Link here

Подробнее читайте здесь и здесь. В настоящее время react.d.ts использует export =, поэтому вам нужно импортировать его, выполнив import * as React .

В основном эти библиотеки имеют только один экспорт. Это представляет в файле определения export =.

person David Sherret    schedule 19.11.2015
comment
Спасибо, это работает. Все еще немного туманно, в чем разница. А как насчет {Router, Route, Link} from 'react-router'? Есть ли способ сделать это? - person Aaron Beall; 19.11.2015
comment
Принятый. :) Тем не менее, все еще немного запутался ... поэтому причина, по которой * as необходима, заключается в том, что d.ts использует export =, но я думал, что это эквивалентно ES6 export default, который будет импортирован с использованием import React from 'react'? Мне непонятно, почему это работало с Babel/Browserify, но семантика, по-видимому, изменилась с TSC. Я думаю, это разница в том, как разрешаются модули? - person Aaron Beall; 19.11.2015
comment
Я также не уверен в синтаксисе ReactRouter.Router. Существующий код JS работал как Router, так как же import * as ReactRouter будет работать во время выполнения? - person Aaron Beall; 19.11.2015
comment
Глядя на транспилированный код Babel, я вижу, что для всех моих импортов по умолчанию (import React from 'react') используется react2 = _interopRequireDefaultExport(react), который проверяет __esModule и выполняет какое-то преобразование, которое я не совсем понимаю, затем мой код ссылается на React через преобразованную переменную react2. Я не вижу ничего подобного в транспилированном коде TSC. Я предполагаю, что это разница. Моя голова кружится. :) - person Aaron Beall; 19.11.2015
comment
Ага! Я узнал, что могу делать import Router from 'react-router/lib/Router'. Это хорошо со мной. - person Aaron Beall; 20.11.2015
comment
Беру свои слова назад, пока TSC понравилось import Router from 'react-router/lib/Router' транспилированный JS не заработал. Он скомпилировал ссылки на Router как Router.default, что неверно — сама ссылка Router верна. - person Aaron Beall; 20.11.2015

Чтобы использовать следующий синтаксис:

import React from 'react';

Вам нужно установить эти два флага в tsconfig.json:

{ "allowSyntheticDefaultImports": true, "esModuleInterop": true }

Протестировано со следующими версиями:
Typescript 2.9.2
@types/react 16.4.7
react 16.4.1

person ibasoni    schedule 24.07.2018