Generics
Class
class Collection<TypeOfItem> {
items: Array<TypeOfItem> = [];
add(item: TypeOfItem){
this.items.push(item);
}
remove(item: TypeOfItem) {
const index = this.items.findIndex(i => i === item);
this.items.splice(index, 1);
return this.items;
}
}
const myCollection = new Collection<number>();
myCollection.add(1);
myCollection.remove(1);
const myCollectionString = new Collection<string>();
myCollectionString.add('1')
Function
function removeItemFromArray<TypeOfItem>( arr: Array<TypeOfItem>, item: TypeOfItem ) : Array<TypeOfItem> {
const index = arr.findIndex (i => i == item);
arr.splice(index, 1);
return arr;
}
removeItemFromArray<number>([1,2,3], 2)
removeItemFromArray(['1','2','3'], '2');
TypeScript and React: Getting Started
TypeScript is a natural fit for React, not only because TypeScript is a full fledged JSX compiler. Which means that you don’t need a huge building setup. TypeScript includes everything you need. One thing you might want is a bundling tool. Parcel is one choice with easy to no configuration, but you can also use Webpack.
The TypeScript docs have some documentation on React and Webpack and might be a good start.
App.tsx
import React, { Component } from 'react'
import logo from './logo.svg';
import './App.css';
import Accordion from './Accordion';
interface GreetingProps {
name: string
}
const Greeting = ({name}: GreetingProps) => <h1>Hello to you {name} !</h1>
//const Greeting = ({name}: {name: string}) => <h1>Hello to you {name} !</h1>
class App extends Component {
render() {
return (
<div className = "App">
<header className = "App-header" >
<Greeting name = "Harry" />
<Accordion preview={<h1>Banana !</h1>}>
Welcome to App Page
</Accordion>
</header>
</div>
)
}
}
Accordion.tsx
import React, { Component } from 'react';
interface AccordionProps {
children: React.ReactNode;
preview: React.ReactNode;
}
interface AccordionState{
open: boolean;
}
export default class Accordion extends Component <AccordionProps, AccordionState>{
state = {
open: false
};
render(){
if(this.state.open){
return(<>
{this.props.children}
<br/>
<div onClick={() => this.setState({open: false})}>Close</div>
</>)
}
return(<>
{this.props.preview}
<br/>
<div onClick={() => this.setState({ open: true})}>Open</div>
</>)
}
}
Reference
In this section:
NPM packages to install
tsconfig.json compiler options
Can’t get Nested JSON Object Property Typescript
// Create a type for the expernal data.
interface Data {
rates: {
[currency: string]: number
}
base: string
date: string
}
// Result of `JSON.parse()` will be `any`, since typescript can't parse it.
const untypedData = JSON.parse(`{
"rates": {
"CAD": 1.4591,
"HKD": 8.6851,
"ISK": 135.9,
"PHP": 56.797,
"DKK": 7.4648
},
"base": "EUR",
"date": "2019-07-25"
}`)
// Cast the untyped JSON to the type you expect it to be.
const data: Data = untypedData
// Use the data according to it's type.
alert(data.rates.CAD)
[@types/react] cannot setState with dynamic key name type-safe
interface State {
name: string;
age: number;
}
type StateKeys = keyof State;
function dynSetState(key: K, value: State[K]) {
this.setState({ [key]: value }); // fails; if only this worked...
this.setState({ [key]: value } as Pick); // clean cast works
this.setState((s, _) => ({ ...s, [key]: value })); // avoids cast, but changes js
}
dynSetState("name", "a"); // works as expected
dynSetState("name", 1); // fails as expected
dynSetState("age", "a"); // fails as expected
dynSetState("age", 1); // works as expected
Reference
why should we use webpack?
Modules Chapter
React JS & Typescript Hello World Example
without type declarations
Reference
getting-started
How to properly define state in React components
React TypeScript: Basics and Best Practices
Stateful React Components with Typescript
Typescript React Cheatsheet
React with Typescript and Webpack