Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript definition for preact #140

Closed
idchlife opened this issue May 5, 2016 · 43 comments
Closed

TypeScript definition for preact #140

idchlife opened this issue May 5, 2016 · 43 comments

Comments

@idchlife
Copy link

idchlife commented May 5, 2016

I'm wondering... Would you be interested in participating in TypeScript and all? :D
I'm looking into it right now (choosing between it and flowtype) and thinking about creating definiton file. Also there is some movement about flow-type definitions, as I see in their repository. So maybe two definitions will be better. What do you overall think about flow and typescript?

@developit
Copy link
Member

I like the both, but have not used either extensively. I think the first step would be putting togrther a d.ts, which is doable by hand I believe. Would seem to be worthwhile?

@idchlife
Copy link
Author

idchlife commented May 5, 2016

@developit I will think about it for some time (idea just popped up in my head). Still learning about TS definitions, but https://github.com/flowtype/flow-typed also seem to be interesting.

@kruczy
Copy link
Contributor

kruczy commented May 6, 2016

I'm using preact with typescript though my definition file is very minimalistic and not really applicable to all uses, I'll try to find some time this weekend to refine it into a proper definition and publish on tsd and/or here

@idchlife
Copy link
Author

idchlife commented May 6, 2016

@kruczy do you use definition file and preact as external library including it via <script> tag?

@styfle
Copy link
Contributor

styfle commented Jun 5, 2016

We can likely use react.d.ts from DefinitelyTyped as a starting point since the interface is so similar.

@mvindahl
Copy link

mvindahl commented Jun 9, 2016

Also, DefinitelyTyped seems like a good place to submit a future preactjs typescript definition file. A lot of projects work this way. A good thing about using DefinitelyTyped is that is does not imply any expectation that the preactjs keeps the .d.ts up-to-date as it will not be a core part of the project.

Anyway, I plan to give preact a spin in a Typescript project. If I end up liking it, I'll be happy to lend a hand with creating typescript definitions.

@PaulBGD
Copy link

PaulBGD commented Jun 10, 2016

@mvindahl DefinitelyTyped is deprecated, check out the typings project.

@styfle
Copy link
Contributor

styfle commented Jun 10, 2016

@PaulBGD Where do you see its deprecated? The typings project pulls from dt as a source.

@PaulBGD
Copy link

PaulBGD commented Jun 10, 2016

@styfle Sorry my bad, just the tsd tool is deprecated. The typings tool that replaced it however uses a JSON file to pull the typings file from a source (like NPM or a repository). We could just link to the preact repository.

@developit
Copy link
Member

For what it's worth, if you guys come up with the d.ts, I am more than happy to have it in the repo root.

@PaulBGD
Copy link

PaulBGD commented Jun 10, 2016

Here's what I came up with in a few minutes: https://gist.github.com/PaulBGD/bb3c7da48551e8130d3477a7a72f7d53

The biggest issue is that preact doesn't export a createElement method which is what TypeScript is expecting (instead preact uses h.) If you exported h as the alias createElement then you wouldn't need the hacky-preact-inject (which is a badly named) file.

EDIT: So now I'm using babel on top of TypeScript so that I can use h.

@developit
Copy link
Member

@PaulBGD Looks good. That definition seems like it would work right out-of-the-box with preact-compat, for what it's worth.

There is actually a proposal to alias h() as createElement() in #168, but I'm slightly hesitant because it is purely a compatibility feature. Normally those types of things go into preact-compat, and we get a nice clean separation between Preact's core functionality (a vdom renderer with very react-like semantics but no extra weight) and the full-on react compatibility (emulating deprecated APIs or decisions like React.createElement that promote library lock-in).

By the way - is your setup open-source? I'm curious about the Babel + TypeScript workflow.

@PaulBGD
Copy link

PaulBGD commented Jun 12, 2016

Yeah. I honestly like what you're doing with leaving the react compatibility inside of preact-compat and I think that because of it you don't need to add createElement to preact. That's just my opinion though.

As for my setup, I'm using rollup, which makes it really easy to handle TypeScript and Babel. Just setting target: es2015 in the tsconfig.json is all you need to do on the TypeScript side. It's not open sourced but I could definitely release a few files for the setup.

@developit
Copy link
Member

@PaulBGD any plans to migrate that Gist to a full repo?

@PaulBGD
Copy link

PaulBGD commented Jul 9, 2016

I could, but I'd rather not require people to import "hacky-preact-inject". I think there's not much of a downside to including createElement as an alias to h, since this is a react alternative.

If you want to throw it into a repo, be my guest. It's MIT.

@developit
Copy link
Member

I poked around the TypeScript project a bit and it seems like there are no open issues for being able to actually set the JSX pragma, which means every library would have to use the same .createElement() name. To me, that's a missing feature in TypeScript, since other transpilers will produce hyperscript with a fully configurable pragma/reviver function.

I've opened microsoft/TypeScript#9582 to address the issue directly. Hopefully they are receptive!

@PaulBGD
Copy link

PaulBGD commented Jul 9, 2016

Good idea.

@styfle
Copy link
Contributor

styfle commented Jul 9, 2016

Nice! The TS guys are usually pretty active so hopefully they respond soon.

@mikekidder
Copy link

mikekidder commented Jul 10, 2016

@developit There weren't open issues, but did you see microsoft/TypeScript#5546?

Seems they are working on bigging transformation initiative to support this.
See last comment in regards to microsoft/TypeScript#5595

Update - See now someone posted link in your Issue on Typescript page.. Anyways, posted links here for brevity....

@kruczy
Copy link
Contributor

kruczy commented Jul 28, 2016

my typings for preact: https://gist.github.com/kruczy/858a231937f562563e1a8c9ba43292b4

should work fine for most cases, maybe we should include something like this in the lib so typings will load automatically @developit ?

@developit
Copy link
Member

@kruczy sorry for the lag there - yes, I'd love to bundle these in. It's a negligible weight added to the module, and means we can provide a better DX for TypeScripters. Want to do a PR? I'm not really clear on how the definition gets associated with a given library, so I'll defer that to you 😉

@kruczy
Copy link
Contributor

kruczy commented Aug 1, 2016

Hey, ill have another look through the api to make sure I am not missing something and will PR today

@kruczy
Copy link
Contributor

kruczy commented Aug 1, 2016

added some improvements and the pr is here: #251

@developit
Copy link
Member

developit commented Aug 1, 2016

Celebrate, friends, for we now have a TypeScript definition! 💃
Feel free to keep things going on this issue, I'm just closing it because I get anxious when we approach 10 open issues 💅

@daslicht
Copy link

daslicht commented Nov 3, 2016

is there somewhere a TypeScript / Preact example , please?

@PaulBGD
Copy link

PaulBGD commented Nov 3, 2016

@daslicht Something like this?: https://www.typescriptlang.org/docs/handbook/jsx.html
Just remember to import preact instead of react though.

@daslicht
Copy link

daslicht commented Nov 3, 2016

thanks, i will play around with it

@idchlife
Copy link
Author

idchlife commented Nov 8, 2016

Oh boy, we definetely need to make example. RIght now configuring typescript with preact, when I will be finished I'll post here link or steps to use preact with typescript.

@developit
Copy link
Member

That would be awesome.

Perhaps a section on the website for "use with typescript" would be worth it?

@idchlife
Copy link
Author

idchlife commented Nov 9, 2016

@developit edit it for your needs! Also, to everyone - guys, test this out and propose changes too!
@daslicht

How to use Preact with TypeScript (node >6.3)

Using:

  • webpack <2 version (>=2 doc will be in future)
  • awesome-typescript-loader loader
  • babel loader (for transpiling es6 files generated by typescript-loader) with react preset
  • typescript ^2

webpack.config.js

const babelLoaderOptions = {
  presets: ['es2015', 'stage-0'],
  plugins: [
    ['transform-react-jsx', {
      pragma: 'h'
    }],
  ]
};

module.exports = {
  entry: './app.tsx',
  output: {
    filename: 'app.js',
    path: __dirname
  },
  module: {
      {
        test: /\.tsx?$/,
        loader: `babel?${JSON.stringify(babelLoaderOptions)}!awesome-typescript-loader?tsconfig=./tsconfig.json`,
      }
    ]
  }
};

What's going on here?

loader: `babel?${JSON.stringify(babelOptionsQuery)}!awesome-typescript-loader?tsconfig=./tsconfig.json`,

First, awesome-typescript-loader transpiles code into es6 (look into tsconfig.json section), leaving untouched all jsx syntax. Then babel takes from there and transpiles it all to es5 browser-compatible code.

tsconfig.json

{
  "compilerOptions": {
    "target": "es2015",
    "jsx": "preserve"
  },
  "files": [
    "./app.tsx",
    "./node_modules/preact/dist/preact"
  ]
}

"jsx": "preserve" means, that typescript won't be alerting and transpiling jsx syntax. Without it, typescript will alert about syntax error.
"target": "es2015" so you can use different new things in typescript, like async/await etc. But, you can config it for your own needs of course.

"./node_modules/preact/dist/preact"

^^^ this can be changed relatively where is your script is and where is node_modules folder is. This line is including preact.d.ts into project so it can be used by typescript and your ide for auto-completion.

And our app.tsx:

/// <reference path="../node_modules/preact/dist/preact.d.ts" />

import { h, Component, render } from "preact";

interface PropsType {
  value: string;
}

class AppComponent extends Component<PropsType, Object> {
  public render(props: Object, state: Object) {
    return (
      <div>My first Preact TypeScript app!</div>
    );
  }
}

render(<AppComponent value="this-is-string" />, document.getElementById("app"), true);

This line exactly is used for TypeScript to know that there is exactly TypeScript module "preact".

/// <reference path="../node_modules/preact/dist/preact.d.ts" />

@daslicht
Copy link

daslicht commented Nov 11, 2016

@developit: The main point why I prefer TS over Babel is code completion.
You could implement a TS Class once and than you never have to remember its public functions and properties , you just can select them from a list. That makes this so fast to code without typing your finger wound when using long descriptive names :)

@daslicht
Copy link

daslicht commented Nov 17, 2016

@idchlife: Why do you not just use ts-loader and leave babel ?

It would be nice if there would be @types/preact
see: http://microsoft.github.io/TypeSearch/

That way we wouldn't need any references at all !

@developit
Copy link
Member

@daslicht that looks pretty slick. I wonder what it'd take to get preact.d.ts into DefinitelyTyped?

@idchlife
Copy link
Author

@daslicht could you please provide instructions how to make it work with ts-loader? It will be helpful to others!

@PaulBGD
Copy link

PaulBGD commented Nov 17, 2016

@developit @daslicht We could add it to NPM under ~types, however including it in the main project accomplishes the same thing and requires 1 less package.

@Avol-V
Copy link

Avol-V commented Jan 1, 2017

It's wrong idea! The better place for .d.ts is in package itself.

Read the documentation http://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html

If you control the npm package you are publishing declarations for, then the first approach (bundling with your npm package) is favored. That way, your declarations and JavaScript always travel together.

@jc4p
Copy link

jc4p commented Jan 6, 2017

@idchlife here is an example using latest preact, Typescript, Webpack 2 beta, and ts-loader: https://gist.github.com/jc4p/7e99f1ec253e95cdc25debba2d8eaf33

@developit
Copy link
Member

@jc4p we should link that from somewhere. Super useful.

@daslicht
Copy link

I get the following error in vs code for html elements :

[ts] 'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.
(property) JSX.IntrinsicElements.h1: JSX.HTMLAttributes

Idea?

@daslicht
Copy link

@MonsieurMan
Copy link

Hey guys, what's the status, is there any recent material ? VSCode is still unable to locate the typings provided in the package.

@marvinhagemeister
Copy link
Member

@MonsieurMan preact works right out of the box with the built-in typings for about a year. If you're running into an issue feel free to open a new one.

@MonsieurMan
Copy link

MonsieurMan commented Oct 11, 2018 via email

marvinhagemeister added a commit that referenced this issue Mar 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests