You can measure the time elapsed during the execution of TypeScript commands by keeping a reference to the start
time and then subtracting the current
time at any point on your program from that start
time to obtain the time elapsed between two points in time.
const start = new Date().getTime();
// Run some code..
let elapsed = new Date().getTime() - start;
Let's create two helper functions to get the current time (i.e. now
) and the elapsed
time at any point from that moment.
// Returns current time
// (and, if provided, prints the event's name)
const now = (eventName = null) => {
if (eventName) {
console.log(`Started ${eventName}..`);
}
return new Date().getTime();
}
// Store current time as `start`
let start = now();
// Returns time elapsed since `beginning`
// (and, optionally, prints the duration in seconds)
const elapsed = (beginning = start, log = false) => {
const duration = new Date().getTime() - beginning;
if (log) {
console.log(`${duration/1000}s`);
}
return duration;
}
With those utility functions defined, we can measure the duration of different events.
// A promise that takes X ms to resolve
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Measure duration (while waiting for 2 seconds)
(async function demo() {
const waitInSeconds = 2;
let beginning = now(`${waitInSeconds}-second wait`);
// Prints Started 2-second wait..
await sleep(waitInSeconds * 1000);
elapsed(beginning, true);
// Prints 2.004s
})();
If you found this useful, you might want to join my mailing lists; or take a look at other posts about code, React, and TypeScript.
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
If you found this useful, you might want to join my mailing lists; or take a look at other posts about code, React, and TypeScript.
This example uses regular expressions (RegExp
) to replace multiple appearances of a substring in a string.
const string = `The car is red. The car is black.`;
const replacedString = string.replace(/car|is/g, "·····");
console.log(replacedString);
// returns The ····· ····· red. The ····· ····· black.
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.
Here is an example of nested Promise.all()
calls. We are using the Fetch API to load a given path or URL, then requesting the arrayBuffer()
of each of the responses we get back. This is a trivial problem if we do it all asynchronously, but we want to do something with the output buffers when we have them all available, and not one by one.
Specifically, this code tries to (1) fetch an array of images
; (2) get their array buffers; (3) then obtain their base64
representation. In essence, map an array of images
(by providing their paths or URLs) to their corresponding base64
string.
While this technique works in both TypeScript and JavaScript, the code is only shown in TypeScript.
const images = [/* Array of image URLs (or local path if running in Electron) */]
Promise.all(images.map((url) => fetch(url))).then((responses: any) => {
return Promise.all(responses.map((res: Response) => res.arrayBuffer())).then((buffers) => {
return buffers;
});
}).then((buffers: any) => {
return Promise.all(buffers.map((buffer: ArrayBuffer) => {
return this.arrayBufferToBase64(buffer);
}));
}).then((imagesAsBase64: any) => {
// Do something with the base64 strings
window.console.log(imagesAsBase64);
});
const layerImages = [/* Array of image URLs (or local path if running in Electron) */]
Promise.all(layerImages.map((url) => fetch(url))).then((responses: any) => {
return Promise.all(responses.map((res: Response) => res.arrayBuffer())).then((buffers) => {
return buffers.map((buffer) => this.arrayBufferToBase64(buffer));
});
}).then((imagesAsBase64: any) => {
// Do something with the base64 strings
window.console.log(imagesAsBase64);
});
// source: stackoverflow.com
private arrayBufferToBase64(buffer: any) {
let binary = "";
const bytes = [].slice.call(new Uint8Array(buffer));
bytes.forEach((b: any) => binary += String.fromCharCode(b));
// Inside of a web tab
return window.btoa(binary);
}
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.
A while ago we had the need to grab the App
window variable (exposed by CefSharp) and we were extending the Window
interface to do that. There seems to be a better way to get variables that are define in the Window
environment.
I learned this from this link An advanced guide on how to setup a React and PHP.
If you are defining a variable or object you want to read from React (like in CefSharp, o directly in the HTML like in the screenshot)
// inside of your app entry HTML file's header
<script>
var myApp = {
user: "Name",
logged: true
}
</script>
You can do a declare module 'myApp'
in index.d.ts
, then add the myApp
variable as a external library in Webpack's config file
externals: {
myApp: `myApp`,
},
Then you can import as if it was a module in TypeScript (or JavaScript files) with React
import myApp from 'myApp';
And you can even use TypeScript destructuring technique to get internal properties directly
const { user: { name, email}, logged } = myApp;
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.
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.
const numbers = [1, 3, 100, 24];
for (const item of numbers) {
console.log(item); // 1, 3, 100, 24
}
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.
In TypeScript, as in other languages, Array.map
allows you to apply a function to each of the items on a list or array. You can either pass an existing function which will take each of the items as its input parameter (say, the existing Math.sqrt
function, or one that you define).
let list = [0, 1, 2, 3]; // [0, 1, 2, 3]
list.map(Math.sqrt); // [ 0, 1, 1.414.., 1.732.. ]
Or you can also define a lambda function on-the-go.
let list = [0, 1, 2, 3]; // [0, 1, 2, 3]
list.map((value, key, all) => {
list[key] = value * 2;
}); // [ 0, 2, 4, 6]
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.
To import JSON into your TypeScript code, you need to add the following code to a typings file (a file with a name like *.d.ts
, say, json.d.ts
—but it does not necessarily need to say json)1.
// This will allow you to load `.json` files from disk
declare module "*.json"
{ const value: any;
export default value;
}
// This will allow you to load JSON from remote URL responses
declare module "json!*"
{ const value: any;
export default value;
}
After doing this, you can do the following in TypeScript.
import * as graph from './data/graph.json';
import data from "json!http://foo.com/data_returns_json_response/";
You can then use graph
and data
as JSON objects in your TypeScript code.
I used this code to load a Dynamo JSON graph into TypeScript — just change the .dyn
extension to .json
and it will work with this code.
If you found this useful, you might want to join my newsletter; or take a look at other posts about code, TypeScript, and React.