Skip to content

Instantly share code, notes, and snippets.

@clarkdave
Created April 15, 2018 13:11
Show Gist options
  • Save clarkdave/53cc050fa58d9a70418f8a76982dd6c8 to your computer and use it in GitHub Desktop.
Save clarkdave/53cc050fa58d9a70418f8a76982dd6c8 to your computer and use it in GitHub Desktop.
TypeScript + Gatsby node API
import { resolve } from 'path'
import { GatsbyCreatePages } from './types'
const createPages: GatsbyCreatePages = async ({
graphql,
boundActionCreators,
}) => {
const { createPage } = boundActionCreators
const allMarkdown = await graphql(`
{
allMarkdownRemark(limit: 1000) {
edges {
node {
fields {
slug
}
}
}
}
}
`)
allMarkdown.data.allMarkdownRemark.edges.forEach(edge => {
const { slug } = edge.node.fields
if (!slug) return
// type safe `createPage` call
createPage({
path: slug,
component: resolve(__dirname, '../src/templates/index.tsx'),
context: {
slug,
},
})
})
}
'use strict'
require('source-map-support').install()
require('ts-node').register({
compilerOptions: {
module: 'commonjs',
target: 'es2017',
},
})
exports.createPages = require('./createPages')
interface PageInput {
path: string
component: string
layout?: string
context?: any
}
interface BoundActionCreators {
createPage: (page: PageInput) => void
deletePage: (page: PageInput) => void
createRedirect: (
opts: {
fromPath: string
isPermanent?: boolean
redirectInBrowser?: boolean
toPath: string
}
) => void
}
export type GatsbyCreatePages = (
fns: { graphql: any; boundActionCreators: BoundActionCreators }
) => void
@crhistianramirez
Copy link

crhistianramirez commented Aug 13, 2019

I had to update

const createPages: GatsbyCreatePages = async ({

to

export const createPages: GatsbyCreatePages = async ({

AND

exports.createPages = require('./createPages')

to:

exports.createPages = require('./createPages').createPages

@SimonS
Copy link

SimonS commented Sep 10, 2019

@crhistianramirez same - it fixes the TypeError: gatsbyNode[api] is not a function problems

@orta
Copy link

orta commented Oct 24, 2019

The types for Gatsby ship with Gatsby - you should be able to write code like this instead:

import { GatsbyNode } from "gatsby"
import * as path from "path"

export const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
  const { createPage } = actions

  const blogPost = path.resolve(`./src/templates/blog-post.tsx`)
  const result = await graphql(`
    {
      allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }, limit: 1000) {
        edges {
          node {
            fields {
              slug
            }
            frontmatter {
              title
            }
          }
        }
      }
    }
  `)

  if (result.errors) {
    throw result.errors
  }

@JohnAlbin
Copy link

JohnAlbin commented Mar 22, 2020

@clarkdave, Thanks for sharing this and getting the conversation started.

We can simplify our Gatsby JavaScript files even more, since that JS file can re-export all the exports of a TypeScript file in one line with:

module.exports = require('./path/to/typescript/file');

That means we can have a single TypeScript file with all of our Gatsby API exports. And if we add new API calls to our TypeScript file, they get automatically exported by the JavaScript file without needing to modify it.

Also, ts-node now includes source-map-support. https://github.com/TypeStrong/ts-node/blob/be2c899ca796bd6dc54e074fdb2c5a32df51213d/src/index.ts#L407

With:

  • my comments about module.exports and source-map-support,
  • the fact that boundActionCreators are now deprecated,
  • @orta's comment that "types for Gatsby ship with Gatsby",
  • @jonnybot0's comment (from the Gatsby issue Dave pointed out above) that "ts-node automagically loads tsconfig.json",
  • @jonnybot0's comment that require('ts-node').register() can be put in gatsby-config.js and it will apply to all other gatsby API files, like gatsby-node.js.
  • @assainov's blog post about using gatsby-node.ts instead of gatsby-node.js.

I went ahead and made all those updates in this forked gist: https://gist.github.com/JohnAlbin/2fc05966624dffb20f4b06b4305280f9

@dandv
Copy link

dandv commented May 9, 2020

Thanks @JohnAlbin! I've linked to your gist from this Gatsby issue.

@dillionmegida
Copy link

@crhistianramirez same - it fixes the TypeError: gatsbyNode[api] is not a function problems

@crhistianramirez please, could you explain why your change fixed this error?

@fzyzcjy
Copy link

fzyzcjy commented Feb 4, 2022

Hi, shall we write types.ts or types.d.ts? IMHO maybe that suits the definition of d.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment