扩展从NPM模块导入的React组件(打字稿)

时间:2016-12-21 16:16:30

标签: reactjs typescript

我有一个用打字稿开发的NPM模块。该模块是一个简单的概念验证反应组件:

import * as React from "react";
import * as ReactDOM from "react-dom";

export class COne extends React.Component<{}, {counter : number}> {
    constructor(props: {}, context: any) {
        super(props, context);
    }

    render() {
        return <h1 ref="h1">Test from comp one</h1>;
    }
}

通过使用tsc和适当的tsconfig.json,我生成了js文件。

在另一个项目中,我导入了这个npm模块,我可以毫无问题地渲染组件COne

在第二个项目中,我创建了另一个组件CTwo,该组件扩展了COne

import * as React from "react";
import { COne }  from "repo1";

export class CTwo extends COne {
    constructor(props: {}, context: any) {
        super(props, context);
    }
}

如果我运行tsc --jsx react src/app.tsx,其中app.tsx导入并呈现组件CTwo,一切都很好。但是,如果我运行tsc --jsx react src/app.tsx typings/index.d.ts我的打包文件包含react和react-dom定义(见下文),我会收到此错误

src/app.tsx(8,21): error TS2605: JSX element type 'CTwo' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'CTwo'.

我的typings.json文件包含当前的反应定义和react-dom定义(我正在使用当前的typed-react,因为官方版本缺少JSX的类型,并且在使用noImplicitAny编译时出现问题):

{
  "name": "repo2",
  "dependencies": {
    "react": "github:cantide5ga/typed-react",
    "react-dom": "registry:npm/react-dom#15.0.1+20160826174104"
  }
}

我还安装了ts-node并在REPL中导入了COne from "repo1"CTwo。我看到CTwo在原型上没有render方法(它没有__proto__属性)。

即使我收到错误,但在使用webpack进行处理时,它仍适用于浏览器。请注意,即使我添加了渲染方法,我也会收到另一个错误Property 'setState' is missing in type 'CTwo'.

以下是ts-node的输出:

$ ts-node
> import { CTwo } from "./src/CTwo";
'use strict'
> import { COne } from "repo1";
undefined
> let x = new CTwo({}, {});
undefined
> let y = new COne({}, {});
undefined
> x.__proto__
⨯ Unable to compile TypeScript
[eval].ts (1,3): Property '__proto__' does not exist on type 'CTwo'. (2339)
> y.__proto__
COne { constructor: [Function: COne], render: [Function] }

所以似乎CTwo对象没有正确扩展。我应该使用不同的语法来扩展反应组件吗?

我正在使用typescript 2.1.4。尽管发出错误,生成的CTwo.js“看起来正确”:

"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var repo1_1 = require("repo1");
var CTwo = (function (_super) {
    __extends(CTwo, _super);
    function CTwo(props, context) {
        return _super.call(this, props, context) || this;
    }
    return CTwo;
}(repo1_1.COne));
exports.CTwo = CTwo;

1 个答案:

答案 0 :(得分:0)

在挖掘了一些之后,我发现打字稿找不到repo1定义,尽管它们最初没有被报道。问题发生在repo1的{​​{1}}文件中,我从这里得到了一个提示:Could not find a declaration file for module 'module-name'. '/path/to/module-name.js' implicitly has an 'any' type

关键是,package.json必须更改为main: js/index.js(不带后缀),然后main: js/index可以正确解析repo2并且不存在任何问题。

正如@ Radio-提到的那样,一旦TS能够掌握相关的延期,这样的扩展工作没有问题。