preactjs / preact-compat

ATTENTION: The React compatibility layer for Preact has moved to the main preact repo.
http://npm.im/preact-compat
MIT License
949 stars 148 forks source link

Provide TypeScript definition file #357

Open Holi0317 opened 7 years ago

Holi0317 commented 7 years ago

When mix-and-match preact and react components in typescript, typescript complains as react's element cannot be converted to preact's JSX element. 2017-04-12-22 30 37-screenshot

However, the above code does work as webpack has aliased react to preact-compat and use preact's element.

Output of above code: 2017-04-12-22 30 51-screenshot

What if preact-compat add a typescript definition file that declare preact-compat and aliased react, react-dom modules? This should solve typescript complaining about type error.

Sorry I am not good at writing definition file. But the idea is,

declare module 'preact-compat' {
  // export createElement, propTypes, render, etc.
}

declare module 'react' {
  // I have no idea if the following syntax will work or not. But just to show the idea.
  export {createElement, propTypes, etc} from 'preact-compat'
}

declare module 'react-dom' {
  export {render} from 'preact-compat'
}
developit commented 7 years ago

That seems fine to me, though I don't really know much about typescript. Maybe @mseddon knows 😊

yyhappynice commented 7 years ago

@developit I want to use preact-compat and typescript.
webpack config :

alias: {
  'react': 'preact-compat',
  'react-dom': 'preact-compat'
}

but app.tsx import React from 'react' fail , command return Cannot find module 'react'. Is my configuration a problem? This is my first use preact . Hope to give an example of use preact-compat and typescript. Be deeply grateful ! thanks

developit commented 7 years ago

Hi @yyhappynice - can you post a little more of the surrounding Webpack configuration? It seems like your aliases are not being used. Also just to make sure - you've run npm install preact preact-compat, right?

yyhappynice commented 7 years ago

I submitted the code my project . I didn't find the config mistake. app.tsx file import React from 'react' error . Thanks your help~

developit commented 7 years ago

Hey - I tried a bunch of stuff out locally, but I have no idea what I'm doing when it comes to TypeScript + webpack. I've never seen anyone use ts-loader, only awesome-ts-loader - maybe that's the issue?

yyhappynice commented 7 years ago

OK thinks~ I'll have a try awesome-ts-loader . Hope there is an official example about typeScript + preact-compat

plievone commented 7 years ago

@yyhappynice run npm install @types/react @types/react-dom and try import * as React from 'react' instead of import React from 'react'. Works fine for me with ts-loader and webpack config:

resolve: {
  alias: {
    'react': 'preact-compat',
    'react-dom': 'preact-compat',
  }
}
yyhappynice commented 7 years ago

@plievone At the same time, webpack config need to add ProvidePlugin. Very nice!My project working. thanks ~

new webpack.ProvidePlugin({
   React: 'react'
})
shyr1punk commented 7 years ago

Hi. I was faced with the problem using preact and preact-compat in TypeScript project.

I'm using @types/react for types defenition for external libraries. But @types/react and preact.d.ts are conflict in a JSX namespace - both files includes those namespace.

I solved it with remove JSX section from a @types/react and save it in a project.

Maybe there's another way?

Also migrating from react to preact for TypeScript project isn't trivial. Have you any migration guide for type system (type difference, examples for event types, handlers)?

yyhappynice commented 7 years ago

@shyr1punk Hi you can look at this demo. May help you~

jeffutter commented 7 years ago

I'm running into this issue as well. I am using preact-cli which uses awesome-ts-loader and preact-compat.

I get issues using libraries that depend on react:

[at-loader] ./node_modules/react-apollo/ApolloProvider.d.ts:1:23
    TS2688: Cannot find type definition file for 'react'.

If i install @types/react I get 100's of errors, I'm suspecting due to overlap between preact and react definitions like @shyr1punk suggested.

Mytrill commented 7 years ago

@jeffutter @shyr1punk I think you want to import only from react (not preact) in your code base. This way typescript doesn't link to the types of preact. You should then be able to install @types/react without any problem.

The implication is that you cannot use libraries built on preact and libraries built on react and have the types working for both at the same time (apart from deleting the conflicting type declarations in node_modules/)...

I don't know what would be a proper solution for that. If anyone has any suggestion?

jeffutter commented 7 years ago

@Mytrill Hmm, this does work. It feels a little 'dirty' but I suppose it's fine, react doesn't end up getting imported accidentally or anything like that and flow is happy.

ghost commented 7 years ago

I don't think you really want a Typings for preact-compat, you just install @types/react and @types/react-dom, and the TypeScript editor will depends on them. With alias feature in Webpack your inject preact but mock the IDE that you're using React. Also I didn't understood what negative side-effects could be! But I'm intending to try that this week, and I'd like to update what's will happen ;)

My React components is so complex because they're created in AngularJS scope, and they also inject (render) AngularJS directives in their React scope!! So the preact-compat trying will be very interesting!

Superpat commented 6 years ago

So I'm not sure how this all works. I created a project with preact-cli using the widget template. I modified my preact config to use preact-cli-plugin-typescript and then tried importing react-apollo to use as my graphql-client, which did not work obviously.

I then installed @types/react and @types/react-dom. I started seeing a lot more error messages as mentioned earlier. @Mytrill solution makes sense, but I'm not sure what I would have to do, since simply switching the preact import to react clearly does not work.

marvinhagemeister commented 6 years ago

@types/react cannot be used with preact because both packages declare their JSX types globally. Related: https://github.com/developit/preact/issues/1036