Say you have a form in your React & TypeScript project with a number of input fields, and you want to be able to dynamically update each field (like you can in JS):
class Form extends React.Component<{}, State> {
readonly state: State = initialState;
handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
// TypeScript will complain about this.
this.setState({[event.target.name]: event.target.value})
}
render() {
const { firstName, lastName } = this.state.fields
return (
<div className="wrapper">
<input
type="text"
name="firstName"
value={firstName}
placeholder="first name"
onChange={this.handleChange}
/>
<input
type="text"
name="lastName"
value={lastName}
placeholder="last name"
onChange={this.handleChange}
/>
</div>
)
}
}
String indexing does not come for free in TypeScript as it does in JavaScript, so the above code would not compile as it is.
String-Index-TS to the rescue!!!
Using string-index-ts
we can wrap make our State
object be indexable by string values.
import IStringIndex from "string-index-ts"
interface IFields extends IStringIndex<string> {
firstName: string
lastName: string
}
By extending from the IStringIndex interface, we have made our properties in IFields searchable by string.
Tada!!!
const fields: IFields = { firstName: "Jim", lastName: "Raynor" }
const firstName = fields["firstName"]
It also works with optional properties, like so:
interface IFieldsWithOptionals
extends IStringIndex<string | number | undefined> {
firstName: string
lastName: string
age?: number
}