{"action":"created","issue":{"url":"https://api.github.com/repos/borisyankov/DefinitelyTyped/issues/3615","labels_url":"https://api.github.com/repos/borisyankov/DefinitelyTyped/issues/3615/labels{/name}","comments_url":"https://api.github.com/repos/borisyankov/DefinitelyTyped/issues/3615/comments","events_url":"https://api.github.com/repos/borisyankov/DefinitelyTyped/issues/3615/events","html_url":"https://github.com/borisyankov/DefinitelyTyped/pull/3615","id":56893049,"number":3615,"title":"Split modules react and react/addons; exporting Component<P, S, C> class","user":{"login":"vsiao","id":980673,"avatar_url":"https://avatars.githubusercontent.com/u/980673?v=3","gravatar_id":"","url":"https://api.github.com/users/vsiao","html_url":"https://github.com/vsiao","followers_url":"https://api.github.com/users/vsiao/followers","following_url":"https://api.github.com/users/vsiao/following{/other_user}","gists_url":"https://api.github.com/users/vsiao/gists{/gist_id}","starred_url":"https://api.github.com/users/vsiao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vsiao/subscriptions","organizations_url":"https://api.github.com/users/vsiao/orgs","repos_url":"https://api.github.com/users/vsiao/repos","events_url":"https://api.github.com/users/vsiao/events{/privacy}","received_events_url":"https://api.github.com/users/vsiao/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":15,"created_at":"2015-02-07T02:15:03Z","updated_at":"2015-02-13T00:52:16Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/borisyankov/DefinitelyTyped/pulls/3615","html_url":"https://github.com/borisyankov/DefinitelyTyped/pull/3615","diff_url":"https://github.com/borisyankov/DefinitelyTyped/pull/3615.diff","patch_url":"https://github.com/borisyankov/DefinitelyTyped/pull/3615.patch"},"body":"So... this PR splits `react-0.13.0.d.ts` and `react-addons-0.13.0.d.ts`, with no shared code or interfaces. That feels bad, but there's a good reason why:\r\n\r\n# The Problem\r\n`React.Exports.Component` doesn't have type parameters (it has the type interface `React.ComponentClass<any, any, any>`, which is not extendable by a `class`). The reason this seems to work right now is because `React.Component` references the class in the global `React` module, and not in `\"react\"` or `\"react/addons\"`. So if you `import react`, `react.Component` is not a class.\r\n\r\n# The Solution\r\nExport `class Component<P, S, C>` directly from `module \"react\"` as well as from `module \"react/addons\"`. This has some unfortunate side effects:\r\n\r\n### Top Level Exports\r\nPreviously we managed sharing between `\"react\"` and `\"react/addons\"` by extending `React.AddonsExports` from `React.Exports`. Now that we need to export a class, we can't use export assignment:\r\n```ts\r\nvar exports: React.Exports;\r\nexport = exports;\r\n```\r\nSo every Top Level API method must be exported individually.\r\n```ts\r\nexport function createClass<P, S, C>(...)\r\nexport function createElement<P>(...)\r\nexport class Component<P, S, C> { ... }\r\n```\r\n\r\n### No Shared Interfaces\r\nWe got away with packing all React-related interfaces into the global `React` module because neither `\"react\"` nor `\"react/addons\"` exported any individual elements. Now that they do, If you use\r\n```ts\r\nimport React = require(\"react\");\r\n```\r\nit clobbers the `React` module definition and its interfaces are no longer accessible. This means that we need to either (a) define global interfaces (`ReactElement`, `ReactComponent`, etc.), which is against DT best practices, or (b) declare interfaces in both `\"react\"` and `\"react/addons\"` modules.\r\n\r\n# Attempted Workarounds\r\nmodule merging:\r\n\r\n```ts\r\ndeclare module \"react/addons\" {\r\n    import React = require(\"react\");\r\n    module React { // <---- (*)\r\n        var addons: { ... };\r\n    }\r\n    export = React;\r\n}\r\n```\r\n\r\n_Doesn't work_. The module to be merged `(*)` is ignored completely.\r\n\r\n# So...\r\n\r\nThis is the conclusion that I came to. We should split up `\"react\"` and `\"react/addons\"`, making sure that changes stay in sync between the two files.\r\n\r\n_Bonus features_:\r\n* fixes `static` properties on modern components (needs type annotations)\r\n* write better tests for Top-Level API, making sure that they preserve type information (eg. `ClassicComponentClass -> ClassicFactory -> ReactClassicElement -> ClassicComponent`)\r\n\r\ncc @pspeter3, @jbrantly"},"comment":{"url":"https://api.github.com/repos/borisyankov/DefinitelyTyped/issues/comments/74185763","html_url":"https://github.com/borisyankov/DefinitelyTyped/pull/3615#issuecomment-74185763","issue_url":"https://api.github.com/repos/borisyankov/DefinitelyTyped/issues/3615","id":74185763,"user":{"login":"jbrantly","id":196944,"avatar_url":"https://avatars.githubusercontent.com/u/196944?v=3","gravatar_id":"","url":"https://api.github.com/users/jbrantly","html_url":"https://github.com/jbrantly","followers_url":"https://api.github.com/users/jbrantly/followers","following_url":"https://api.github.com/users/jbrantly/following{/other_user}","gists_url":"https://api.github.com/users/jbrantly/gists{/gist_id}","starred_url":"https://api.github.com/users/jbrantly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbrantly/subscriptions","organizations_url":"https://api.github.com/users/jbrantly/orgs","repos_url":"https://api.github.com/users/jbrantly/repos","events_url":"https://api.github.com/users/jbrantly/events{/privacy}","received_events_url":"https://api.github.com/users/jbrantly/received_events","type":"User","site_admin":false},"created_at":"2015-02-13T00:52:16Z","updated_at":"2015-02-13T00:52:16Z","body":"> But are we heading towards 4x code duplication?\r\n\r\nIf you look at the issue I opened on TypeScript they are saying that you can merge external modules. So it might actually only be 2x code duplication (one for external modules and one for internal). I haven't gotten it to actually work yet though.\r\n\r\nRegarding internal modules, there is really no reason to duplicate code in `react-global.d.ts` and `react-addons-global.d.ts`. As soon as `react-addons-global.d.ts` is referenced anywhere in the project the addons property will be available everywhere. So I think the final version will have either 2x duplication (if we can get that external module merging issue resolved) or 3x."}}