Telerik blogs
KendoReactT2_1200x303

KendoReact is a feature-rich UI component library written with TypeScript. Using the DatePicker as an example, we’ll see how TS can simplify development.

TypeScript (TS) has taken the web development world by storm, and more developers and companies adopt it every year. It offers very useful advantages over JavaScript, such as it creates more maintainable code, provides more confidence during code refactors and helps to catch a lot of bugs before an app even runs.

In this article, we will explore what’s so great about using TypeScript with React and what advantages developers can expect from libraries written with TypeScript when building React applications. We’ll use the KendoReact UI library as an example of such a library. If you’re familiar with TypeScript, you can skip straight to Project Setup and see the difference in using components developed with TypeScript.

Why Should We Use TypeScript?

JavaScript (JS) is a dynamic language that allows developers to create variables and freely assign different types of values. For instance, in JavaScript, we can create a variable with a string and later assign an object to it and vice versa, without any restrictions.

let val = 'Hello World'

val = {
  message: 'Hello World'
}

Let’s say we want to check what is the character at position 3. We could do it by using the string method called charAt.

val.charAt(3) // l

This will work if the val is a string. However, if it’s an object, we would get an error that val.charAt is not a function.

let val = 'Hello World'

val.charAt(3) // works and returns l

val = {
  message: 'Hello World'
}

val.charAt(3) // error

TypeScript helps us to avoid such problems with static typing. We can explicitly specify a type of a variable or let TypeScript infer it.

let val: string = 'Hello world'; 

Now TypeScript knows that the val variable is of type string. We could even skip the : string part, and TypeScript still would know that val should only ever be a string due to type inference. Because of that, if we tried to assign a value of a different type, the TypeScript compiler would throw an error.

TypeScript - value is not assignable error

Instead, we would need to explicitly tell TypeScript that an object can be assigned to the val variable.

type Value = string | {
  message: string
}

let val: Value = 'Hello world';

val.charAt(3)

val = {
  message: 'Hello World'
}

After specifying that the val variable can either be of type string or object that has a message property, we can assign an object to the val variable. However, if we try to call val.charAt after assigning an object, the TypeScript compiler will again throw an error.

TypeScript with React - charAt does not exist on type

That’s how TypeScript with React can help you avoid and catch many bugs early on. The TypeScript compiler will stop if the code doesn’t logically or syntactically make sense. We can’t access the charAt method on an object, as objects don’t have such a method—strings do. Let’s explore other advantages that TypeScript provides, but first, let’s set up a new project.

Project Setup

If you would like to follow this tutorial, you can quickly scaffold a new React project using Vite by running the command below:

$ npm create vite@latest kendo-react-components --template react-ts

After the project is scaffolded, move into it and install all dependencies.

$ cd kendo-react-components && npm install

If you never heard of Vite before, I’ve written an article about it—What Is Vite: The Guide to Modern and Super-Fast Project Tooling.

We also need to install a few KendoReact-specific packages.

$ npm install --save @progress/kendo-react-dateinputs @progress/kendo-react-intl @progress/kendo-licensing @progress/kendo-theme-default

If you would like to learn more about KendoReact’s themes, check out the Building a Design System with Kendo UI article.

Last but not least, we need to import the KendoReact Default theme that we just installed in the App component and update the App.css file.

src/App.tsx

import "@progress/kendo-theme-default/dist/all.css";
import "./App.css";

function App() {
  return (
    <div className="App">
    </div>
  );
}

export default App;

src/App.css

.App {
  text-align: center;
  max-width: 30rem;
  margin: 4rem; auto;
}

That’s it for the setup. Now we can start the dev server by running npm run dev.


You can find full code examples for this article in this GitHub repository and an interactive StackBlitz below.

KendoReact DatePicker With TypeScript

As mentioned before, using TypeScript with React provides benefits that are not available when using vanilla JavaScript. Good examples are type hints and autocomplete suggestions for components. KendoReact is a feature-rich UI component library written in TypeScript, and we will use its React DatePicker component to demonstrate how TypeScript can simplify development.

Type Hints and Autocompletion

Any time we use a component from KendoReact and want to pass some props to them, we will get relevant suggestions. The image below shows the suggestions for the KendoReact DatePicker component.

Datepicker props suggestions including ariaDescribe, ariaLabel, className, etc.

Thanks to TypeScript, we have the available props at hand, significantly reducing the time to read the documentation.

What’s more, relevant suggestions are provided even if your project isn’t using TypeScript, but just JavaScript, as code editors are able to pick up types from components that provide them. Unfortunately, there are limitations to what editors can do.

For instance, let’s say we created a wrapper component around KendoReact’s DatePicker component with some default configurations that should be applied everywhere in our project.

import { DatePicker } from "@progress/kendo-react-dateinputs";

const MyDatePicker = props => {
  return <DatePicker format="MM-dd-yyyy" {...props} />;
};

export default MyDatePicker;

The image below shows what kind of suggestions Visual Studio Code provides for our DatePicker wrapper component.

DatePicker wrapper component suggestions include App, MyDatePicker, but no properties

As you can see, all the relevant prop suggestions for the DatePicker component are gone. The editor doesn’t know that the MyDatePicker component accepts exactly the same props as DatePicker. That’s where TypeScript comes into play.

src/components/MyDatePicker.tsx

import { DatePicker, DatePickerProps } from "@progress/kendo-react-dateinputs";

export type MyDatePickerProps = DatePickerProps & {};

const MyDatePicker = (props: MyDatePickerProps) => {
  return <DatePicker format="MM-dd-yyyy" {...props} />;
};

export default MyDatePicker;

When using TypeScript with React, we can specify what kind of props a component accepts. What’s more, we can even import types from other libraries.

In the code snippet above, we specify that the props object should match the DatePickerProps type, which is imported from the @progress/kendo-react-dateinputs package.

Let’s import and render the MyDatePicker component in the App.tsx file.

src/App.tsx

import "@progress/kendo-theme-default/dist/all.css";
import "./App.css";
import MyDatePicker from "./components/MyDatePicker";

function App() {
  return (
    <div className="App">
      <MyDatePicker  />
    </div>
  );
}

export default App;

Try adding some props. You should see that the relevant autocomplete suggestions are back!

Wrapper DatePicker component suggestions with TypeScript shows the props as before

Catching Accidental Typos With TypeScript

Another benefit of using TypeScript is that if we try to pass a prop that wasn’t specified, TypeScript will let us know about it. It’s especially useful for dealing with typos.

The DatePicker component accepts a prop called format, which is used to configure in what format a date should be displayed. But what if instead of format, we type in formt?

Well, a JavaScript project would run, and we would need to figure out why the DatePicker component isn’t showing the date in the format that we expect. In a TypeScript project, we will see an error message immediately.

DatePicker prop typo error with TypeScript - Property formt does not exist on type IntrinsicAttributes... did you mean format

We can immediately act and correct the mistake thanks to a useful error message. The same applies if we try to pass a value of the wrong type. For example, the format prop is optional, but if it’s passed, it should be a string. If we pass a different type, TypeScript will tell us about it, as shown in the image below.

Wrong prop value type - type number is not assignable to type string

That’s yet another way in which TypeScript can save us a lot of time.

How To Expand Acceptable Props

Since we have a wrapper component, we’re not restricted to the types provided by KendoReact only. Let’s say we would like the MyDatePicker component to accept an error message prop and display it under the DatePicker component. We can modify the MyDatePickerProps type and intersect the DatePickerProps type with our own.

src/components/MyDatePicker.tsx

import { DatePicker, DatePickerProps } from "@progress/kendo-react-dateinputs";

export type MyDatePickerProps = DatePickerProps & {
  errorMessage?: string;
};

const MyDatePicker = (props: MyDatePickerProps) => {
  const { errorMessage, ...datePickerProps } = props;
  return (
    <>
      <DatePicker format="MM-dd-yyyy" {...datePickerProps} />
      {errorMessage ? (
        <p
          style={{ color: "red", margin: "0.5rem 0", display: "inline-block" }}
        >
          {errorMessage}
        </p>
      ) : null}
    </>
  );
};

export default MyDatePicker;

Besides the props defined in the KendoReact library, MyDatePicker component now also accepts the errorMessage prop.

src/App.tsx

import "@progress/kendo-theme-default/dist/all.css";
import "./App.css";
import MyDatePicker from "./components/MyDatePicker";

function App() {
  return (
    <div className="App">
      <MyDatePicker format="dd-MM-yyyy" errorMessage="Please enter the date" />
    </div>
  );
}

export default App;

The image below shows what the component should look like.

DatePicker error message - day-month-year field shows error below it: Please enter the date.

That’s not it for the props and how TypeScript can help with them. Let’s say we decided to remove the errorMessage prop from the wrapper DatePicker component and replace it with an error object instead. TypeScript would highlight every single file where MyDatePicker is used and receives the errorMessage prop.

Types serve as an API contract, and if it’s broken in any place, TypeScript’s compiler will keep us informed. This is extremely useful, especially when we have to refactor a lot of code in various places, as we won’t be able to compile the project until all types match.

This situation could also happen if a third-party component had a breaking change and had some of its props renamed. Because of the difference in types between versions, TypeScript would complain that props passed to the upgraded component are now incorrect. That’s yet another way in which TypeScript can prevent shipping code that is broken.

Summary

TypeScript is a powerful tool that can prevent many bugs from reaching production, as they are caught at compile-time rather than runtime. Type hints, relevant autocomplete with suggestions and error messages in an IDE make the development process much easier and faster and help to keep the codebase more maintainable and simpler to refactor. What’s more, TypeScript combines very well with React and developers can benefit fully from it by using third-party libraries written with TypeScript, such as the KendoReact UI library.

Considering migrating your large React code base to TypeScript? Learn what you may be up against and what might help smooth the process: Using TypeScript With React in a Large Code Base: Challenges and Tips.

Thomas Findlay-2
About the Author

Thomas Findlay

Thomas Findlay is a 5-star rated mentor, full-stack developer, consultant, technical writer and the author of “React - The Road To Enterprise” and “Vue - The Road To Enterprise.” He works with many different technologies such as JavaScript, Vue, React, React Native, Node.js, Python, PHP and more. Thomas has worked with developers and teams from beginner to advanced and helped them build and scale their applications and products. Check out his Codementor page, and you can also find him on Twitter.

Related Posts

Comments

Comments are disabled in preview mode.