react logo typescript logo


Why Add Typescript #

Over the past few years Typescript has gained popularity & almost every new frontend project is based on it.

Changing the site to it makes sense for future development & maintainability.

There are also a lot of advantages over React prop-types.

React prop-types only provides component based type checking.
With typescript we gain type checking over the project at compile time.

Adding Typescript #

Install Dependencies #

pnpm i typescript
pnpm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser

Add a Typescript Config #

tsconfig.json

{
    "compilerOptions": {
        "module": "CommonJS",
        "target": "ESNext",
        "lib": [
            "DOM",
            "ESNext"
        ],
        "strict": true,
        "moduleResolution": "node",
        "sourceMap": true,
        "jsx": "preserve",
        "allowJs": true,
        "noEmit": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "noImplicitAny": false,
        "forceConsistentCasingInFileNames": true,
        "allowSyntheticDefaultImports": true,
    },
    "exclude": [
        "node_modules",
        "public",
        ".cache"
    ]
}
You may want to start with strict: false then work towards enabling strict mode later.

ESLint & Typescript #

Update ESLint config to use Typescript.

updated eslint config with typescript presets

Rename Files #

This can be achieved using bash to rename all js & jsx files in src/ which import react to .tsx & rename all others to .ts.


rename_tsx.sh

#!/bin/bash
rename_tsx() {
  fname="${1##*.}"
  content=$(cat $1)
  if [[ $content == *"import React"* ]]
  then
    mv "$1" "${1%.$fname}.tsx"
    echo "✔ moved jsx file $1 to ${1%.$fname}.tsx"
  else
    mv "$1" "${1%.$fname}.ts"
    echo "✔ moved $1 to ${1%.$fname}.ts"
  fi
}
echo "moving files with JSX content to TSX & others to TS ..."
echo
for file in $(find src -name "*.js" -o -name "*.jsx"); do
  rename_tsx $file
done
echo
echo "all files moved"

From React prop-types to Typescript #

Fortunately I created this site using React prop-types for type checking.
This should make converting the site a bit quicker.

Conversion #

--- a/src/cms/preview-templates/post-preview.js
+++ b/src/cms/preview-templates/post-preview.tsx
@@ -1,8 +1,12 @@
 import React from 'react'
-import PropTypes from 'prop-types'
 import PreviewTemplate from '../../templates/preview-template'

-const PostPreview = ({ entry, widgetFor }) => {
+interface PostPreviewProps {
+  entry: any
+  widgetFor: any
+}
+
+const PostPreview = ({ entry, widgetFor }: PostPreviewProps) => {
   const body = widgetFor('body')
   const title = entry.getIn(['data', 'title'])
   const date = entry.getIn(['data', 'date'])
@@ -11,9 +15,4 @@ const PostPreview = ({ entry, widgetFor }) => {
   return <PreviewTemplate body={body} title={title} date={date} image={image} />
 }

-PostPreview.propTypes = {
-  entry: PropTypes.object.isRequired,
-  widgetFor: PropTypes.object.isRequired,
-}
-
 export default PostPreview
It is possible to automate this process using a tool like jscodeshift.

Source Code #

You can find the full pull request for the above changes of this site on github.

Add Typescript to Components

The source for the site is available on github.

equk-gatsby