私はReactフレームワークを使用するレガシーJavaScriptプロジェクトを使用しています。Reactコンポーネントが定義されていて、それをまったく異なるTypeScript Reactプロジェクト。
JS Reactコンポーネントは、controls.jsxファイルで定義されており、次のようになります。
export class MyComponent extends React.Component {
render() {
return <h1>Hi from MyComponent! Message provided: {this.props.message}</h1>;
}
}
私のTypeScript Reactプロジェクトでは、次のように使用しようとしています。
import * as React from "react";
import * as ReactDOM from "react-dom";
import { MyComponent } from "../JavaScriptProject/controls";
ReactDOM.render(
<MyComponent message="some Nice message"/>,
document.getElementById("documents-tree")
);
エラーメッセージは言う:
JSX要素タイプ 'MyComponent'は、JSX要素のコンストラクタ関数ではありません。タイプ 'MyComponent'にタイプ 'ElementClass'の次のプロパティがありません:context、setState、forceUpdate、props、および2 more.ts(2605)JSX要素クラスは 'props'プロパティがないため、属性をサポートしていません。 (2607)
this の質問で説明されているカスタムタイピングファイルを使用してソリューションをすでに試しましたが、何も変わりません。
JSコンポーネントにはTypeScriptに必要な強く型付けされたプロパティがいくつかあることを理解していますが、tsconfig.jsonではallowJsをtrue:
{
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"experimentalDecorators": true,
"jsx": "react",
"noEmitOnError": true,
"outDir": "lib",
"sourceMap": true,
"target": "es5",
"lib": [
"es2015",
"dom"
]
},
"exclude": [
"node_modules",
"dist",
"lib",
"lib-AMD"
]
}
それがうまくいくことを望みました...
ご協力いただきありがとうございます
Reactはデフォルトをエクスポートしないため、allowSyntheticDefaultImports
をtrue
に変更する必要があります。
(ソース: https://github.com/facebook/react/blob/master/packages/react/index.js )
{
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true, // turn on allowSyntheticDefaultImports
"jsx": "react",
"noEmitOnError": true,
"outDir": "lib",
"sourceMap": true,
"target": "es5",
"lib": [
"es2015",
"dom"
]
},
"exclude": [
"node_modules",
"dist",
"lib",
"lib-AMD"
]
}
また、コンポーネントの小道具の形状を追加する必要があります。たとえば、コードでは:
export class MyComponent extends React.Component<{ message: string }> { ...
私の見方では、2つのオプションがあります。
controls.jsx
という名前のcontrols.t.ds
と同じディレクトリに宣言ファイルを提供できます。このオプションには2つの方法があります。最も簡単なのは、MyComponent
という名前の関数をエクスポートすることです。
export function MyComponent(): any;
2つ目は、コンポーネントのクラス構造を模倣する変数をエクスポートすることです。
interface Element {
render(): any;
context: any;
setState: any;
forceUpdate: any;
props: any;
state: any;
refs: any;
}
interface MyComponent extends Element {}
export var MyComponent: {
new(): MyComponent;
}
import React from 'react';
import {MyComponent as _MyComponent} from '../project-a/Controls';
interface MyComponent extends React.Component {}
const MyComponent = (_MyComponent as any) as {
new(): MyComponent;
};
export {MyComponent};
次に、MyComponent
を使用するファイルで、代わりにその新しいファイルからインポートします。
これらはすべて非常に大まかな解決策ですが、TypeScriptではプロジェクトに関連するモジュールを定義できないため、これが唯一の解決策だと思います。
declare module "../project/Controls" {
}
お役に立てれば。
これが、サンプルアプリケーションで使用している参照の構成です。
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": [
"src"
]
}
package.json
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
"@testing-library/user-event": "^7.1.2",
"@types/jest": "^24.0.23",
"@types/node": "^12.12.18",
"@types/react": "^16.9.16",
"@types/react-dom": "^16.9.4",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-scripts": "3.3.0",
"TypeScript": "^3.7.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
私はwebpackを使用していません。