You can directly assign new properties.
(window as any).talk = () => { console.log(`Hello!`) }
You can extend the Window
interface with typings and then assign the property values.
declare global {
interface Window {
talk: () => void
concat: (words: string[]) => string
}
}
window.talk = () => { console.log(`Hello!`) }
window.concat = (words: string[]) => {
return words.join(`, `)
}
I've been doing a lot of React and TypeScript work lately. It had been a few years since I worked with them on a daily basis, and things are improving a lot. It's a breeze to work with some of these technologies to build web apps, and one of the newest additions that works well is Vite.
Is anyone else working with React these days? I will cover some of my learnings on YouTube and want to get a sense of interest. (Let me know on Discord.)
What's cool is that frameworks such as ONNX and TensorFlow have wide support to export and run models in the browser (web workers, WebGPU, WebAssembly) and you don't even need to build microservices for certain models. (Plus there's now support for Node.js to run in the browser as well!)
Here are three ways to define a React component in TypeScript which, in the end, are three ways to define a function in TypeScript—React components are JavaScript functions.
const MyComponent = (text: string) => <>{text}</>
const MyComponent = (text: string) => {
return (
<>{text}</>
)
}
function MyComponent(text: string) {
return <>{text}</>
}
import * as React from 'react'
import * as Server from 'react-dom/server'
let Greet = () => <h1>Hello, Nono!</h1>
console.log(Server.renderToString(<div><Greet /></div>))
// <div><h1>Hello, Nono!</h1></div>
The tricky part is running this code.
You first need to build it, say, with esbuild
, then execute it.
# Build with esbuild.
esbuild RenderToString.jsx --bundle --outfile=RenderToString.js
# Run with Node.js.
node RenderToString.js
# <div><h1>Hello, Nono!</h1></div>
How to build a website with the Next.js React framework and TypeScript.
# TL;DR
npx create-next-app@latest --ts
cd my-app
npm run build
npm start
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
Here is the fastest way to create a Next.js React app with TypeScript. For the step-by-step version, take a look at the longer version.
Let's use npx and create-next-app
.
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/nonoesp/next-learn/tree/master/basics/typescript-final"
# Enter the app's directory
cd nextjs-app
# Run the app in development
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You should be able to access the site at http://localhost:3000.
npm run build
npm start
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You can watch my step-by-step video on How to build a Next.js app with React & TypeScript.
Here are the simplified steps to create a Next.js React app and add TypeScript to the mix. This tutorial combines my Create a Next.js app and Add TypeScript to Next.js posts.
Let's use npx and create-next-app
.
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
# Enter your app's directory
cd nextjs-app
# Create an empty TypeScript configuration file
touch tsconfig.json
# Install TypeScript, React Types, and Node Types
npm install --save-dev typescript @types/react @types/node
You can customize your TypeScript in tsconfig.json
.
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You should be able to access the site at http://localhost:3000.
npm run build
npm start
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
index.js
into index.tsx
Your application is now ready to be written in TypeScript. The example we've used only has one file named index.js
. Rename it to index.tsx
and re-write the JavaScript code (and any new code you add to the app) in TypeScript.
You can watch my step-by-step video on How to build a Next.js app with React & TypeScript.
Here are the steps to add TypeScript to your Next.js React application.
I assume you have a Next.js React application that can run in development mode. If that's not the case, Create a Next.js app first.
# Enter the directory of your app
cd nextjs-app
# Run Next.js in development
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
If you can access your site at http://localhost:3000, you're good to go.
tsconfig.json
file# Create an empty TypeScript configuration file
touch tsconfig.json
Simply by creating a tsconfig.json
file and restarting the application, Next.js will warn us that we're trying to work with TypeScript and have to install a set of required dependencies.
# Stop the running app with `CMD + C` (or `CTRL + C` on Windows)
# Run Next.js in development once again
npm run dev
You should receive the following warning when restarting the app.
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
It looks like you're trying to use TypeScript but do not have
the required package(s) installed.
Please install typescript, @types/react, and @types/node by running:
npm install --save-dev typescript @types/react @types/node
If you are not trying to use TypeScript, please remove the
tsconfig.json file from your package root (and any TypeScript
files in your pages directory).
npm install --save-dev typescript @types/react @types/node
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
# We detected TypeScript in your project and created a tsconfig.json
# file for you.
Note that Next.js detected the tsconfig.json
file, verified our dependencies were installed, and then populated our empty TypeScript configuration file with a boilerplate JSON object.
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
index.js
into index.tsx
Your application is now ready to be written in TypeScript. The example we've used only has one file named index.js
. Rename it to index.tsx
and re-write the JavaScript code (and any new code you add to the app) in TypeScript.
If you want to learn more, you can watch my video on How to build a Next.js app with React & TypeScript and take a look at Next.js's official TypeScript tutorial.
As the official Create a Next.js App tutorial says, "there are many important details you need to consider to build a complete web application with React from scratch," but here I'm trying to get started as fast as possible.
Let's use npx and create-next-app
.
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
Your fresh Next.js app is now in the nextjs-app
directory.
Now enter the directory and run the app in development mode.
cd nextjs-app
npm run dev
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
You should be able to access the site at http://localhost:3000.
npm run build
npm start
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
If you want to use TypeScript instead of JavaScript on your Next.js React app, read how to Add TypeScript to Next.js. I also have a step-by-step video on How to build a Next.js app with React & TypeScript.
I'm writing a series of posts on how to create a Next.js React app with and without TypeScript, trying to summarize the required steps.
# Create a Next.js React JavaScript app with npx
npx \
create-next-app nextjs-app \
--use-npm \
--example \
"https://github.com/nonoesp/next-learn/tree/master/basics/learn-starter"
# Enter the app's directory
cd nextjs-app
# Start the app in development mode
npm run dev
# > dev
# > next dev
#
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
# wait - compiling...
# event - compiled client and server successfully in 944 ms (113 modules)
You should be able to access the site at http://localhost:3000. =)
Nesting <a>
HTML elements is forbidden. Here's an example:
<a href="https://nono.ma">
Go to my website, or to my
<a href="https://nono.ma/about">
about page
</a>.
</a>
A link to the about page is nested inside of a link to the root of this site.
npx
and create-react-app
make it easy to create a new app running React and TypeScript.
npx create-react-app my-app --template typescript
Then you go into the folder and run the app.
cd my-app
npm start
You can create a JavaScript (non-TypeScript) app by removing the last bit—--template typescript
. And you can also run the app with yarn start
.
If, as I was, you're not getting the app working, you might have an older global installation of create-react-app
. In my case I installed it with npm install -g create-react-app
(which I could verify by running create-react-app -V
on the Terminal. To make sure npx
uses the latest version of create-react-app
you need to uninstall the global version installed with npm
.
npm uninstall -g create-react-app
In trying to export my React's Redux store
from index.tsx
to be used somewhere else outside of the React application, I was getting an Invariant Violation:
Target container is not a DOM element
error while running Jest tests (with Enzyme and Webpack) in the App
component (App.tsx
).
I found a solution to this error for my use case, which was using the same Redux store React is using outside of React.
The initial code that didn't work when testing React looked like this.
// index.tsx
import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { applyMiddleware, compose, createStore } from "redux";
import App from "./components/App";
import { rootReducer } from "./store/reducers";
import { initialState } from "./store/state";
const middlewares = [];
export const store = createStore(
rootReducer,
initialState,
compose(applyMiddleware(...middlewares)),
);
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root"),
);
Separate the Redux store logic into a new file named store.ts
, then create a default export
(to be used by index.tsx
, i.e., the React application) and a non-default export with export const store
(to be used from non-React classes), as follows.
// store.ts
import { applyMiddleware, compose, createStore } from "redux";
import logger from "redux-logger";
import { rootReducer } from "./store/reducers";
import { initialState } from "./store/state";
const middlewares = [];
export const store = createStore(
rootReducer,
initialState,
compose(applyMiddleware(...middlewares)),
);
export default store;
// updated index.tsx
import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import App from "./components/App";
import store from "./store";
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root"),
);
// MyClass.ts
import { store } from "./store"; // store.ts
export default class MyClass {
handleClick() {
store.dispatch({ ...new SomeAction() });
}
}
default
exportA small note before you go. Here is how to use the default
and the non-default exports.
default export store;
is used with import store from "./store";
export const store = ...
is used with import { store } from "./store";
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.
React Google Charts is "A thin, typed, React wrapper over Google Charts Visualization and Charts API." View the source on GitHub.