Next.js: Add typescript example

Created on 26 Oct 2016  ·  24Comments  ·  Source: vercel/next.js

this looks _awesome_ but I also really like TypeScript.
is there any way to integrate typescript into the workflow?

Most helpful comment

If you are using VSCode it is also possible to hide derived JS file.

All 24 comments

Custom webpack config would make this happen: #40

You don't need a custom webpack config (althouh it _would_ be nice). There's nothing preventing you from using typescript as-is. For example:

screen shot 2016-10-29 at 1 06 46 am

tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "jsx": "react",
        "noImplicitAny": false,
        "sourceMap": false
    }
}

As I don't think next.js has any typings (yet), you might need a next.d.ts file in the typings folder to define some things. For example:

next.d.ts:

declare module 'next/head' {
    import * as React from 'react';

    export default class Head extends React.Component<any, any> {}
}

declare module 'next/link' {
    import * as React from 'react';

    export default class Link extends React.Component<any, any> {}
}

That should get you rolling. You can use the same approach for other next specific modules.

To make the workflow a little smoother you can run node_modules/.bin/tsc --watch (or just tsc --watch if you have TypeScript installed globally) along with next, so that changes to your .tsx files get compiled automatically and cause next.js to reload.

wow @rossipedia i have been doing literally this exact thing locally, and it works!

it occurred to me moments after i opened this issue that it should be quite possible to layer tsc -p . on top of next, and of course it's that easy.

typings are proving a little more insidious than that because the library injects props.url into pages and treats getInitialProps slightly differently. so i'm still trying to figure out how to correctly type those.

When we add custom babel / webpack config, I would love to have a TypeScript example and a Flow example. @rossipedia thanks a lot for the temporary workaround. If you'd be up for documenting the temporary solution in the Wiki, I think a lot of people would appreciate it!

If you are using VSCode it is also possible to hide derived JS file.

@rauchg I'm traveling this weekend, but if nobody else gets to it I'd be happy to add a page to the wiki, I can whip it up during my flight tomorrow

trying to get running with typescript - things were going great until I decided to configure the page header...

import Head from "next/head";
...
render() {
        return (
            <div>
                <Head>
                    <title>Yo!</title>
                </Head>
                <div>unicorn</div>
            </div>
        );
    }

React.createElement starts complaining that the element shouldn't be null. It appears that the default export from "next/head" is null:

screen shot 2016-11-02 at 1 05 43 pm

anyone else seeing this in a typescript project?

Have you tried

const Head = require('next/head')

?

Of course

On Nov 5, 2016, 6:10 AM -0700, Giacomo Rebonato [email protected], wrote:

Have you tried

const Head = require('next/head')

?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub (https://github.com/zeit/next.js/issues/96#issuecomment-258610479), or mute the thread (https://github.com/notifications/unsubscribe-auth/AEJIOpmnMfMDjoRYN9vMy5QR940DTmxJks5q7IAygaJpZM4KhdeG).

Ok, if you write it like this, it will work

const Head = require('next/head').default

I found it pretty easy to just edit the gulpfile to also compile .ts files.

https://github.com/zeit/next.js/blob/master/gulpfile.js#L123

Why not compile .ts files with typescript and .js files with babel by default?

With Webpack you mean?
I like TypeScript and I will be happy enough when we can customise the Webpack configuration.

@skhavari your issue is a known module interop issue and adding '.default' is not needed.
Try telling TypeScript to emit 'es6' code (which webpack will pick up) and use 'node' modules resolution:

{
  "compilerOptions": {
    "target": "es6",
    "moduleResolution": "node",
    "jsx": "react"
  },
  "filesGlob": [
    "pages/**/*.tsx"
  ]
}

I also add 'tsc' in my scripts like so:

...
    "dev": "tsc && next",
    "build": "tsc && next build",
    "start": "tsc && next start"
...

@rossipedia I think the same can be achieve by having your own gulp file that compiles ts files and move them to the page dir where next picks them up and reloads them right?

@gozes I don't see why not. I've rarely used gulp, but from what I know of it that seems like a fairly standard use case.

So here's my attempt https://github.com/jagreehal/next-typescript

It works fine apart from the page reloading twice as I don't think there is a way to configure files NOT to be watched by the hot-reloader.

If additional ignore entries could be added here via next.config.js then a solution like this might work.

@jagreehal That's really cool 💯 I'll have a look into adding the ignore config option in next.config.js.

I made a PR to @jagreehal example to separate the ts and js. Now the ts is in src but is there a way to point next to a different folder than the root? Then the output folder for tsc could be dist instead which would make the folder structure look much cleaner!

@timneutkens thanks. Let me know if I can help adding config option in next.config.js.

I have created a PR with a TypeScript example that works with just running npm run dev.
Any suggestions is appreciated.

https://github.com/zeit/next.js/pull/845

@giacomorebonato awesome stuff! left you some review comments 🍰

Any suggestion on how to use TS with custom server? I wanted to use Express and have some trouble. Basically doing import next from "next" fails with server.ts(2,18): error TS2307: Cannot find module 'next'. so I guess I'm missing some typings, right?

--edit--
OK, got it working by specifying next version 2.0.0-beta

With TS 2.1 and above (if I remember correct) you no longer need the typings, if it's in node_modules it can always be imported as any.

Update: Sorry for replying to such an old post, I didn't see the notification mail until now. Google Inbox grouped it together with another notification mail and I didn't notice the date.

Was this page helpful?
0 / 5 - 0 ratings