DEV Community

Jack Herrington
Jack Herrington

Posted on • Originally published at Medium on

Are Typescript Types Alone Enough Documentation?

Here is an interesting question; are the types in your Typescript project enough documentation, on their own, to allow someone to learn the library?

That was the question I asked myself when I saw the Amazon had released a React UI library for AWS. They only released the code and the Typescript types. No documentation. No storybook or styleguidist. Just the code and the types.

Now I love digging into UI libraries. And this was a fun challenge. Can I learn the library from just the source? So I started a Create React App using the typescript template, then installed the @awsui/components-react library and started my sleuthing.

The first thing to realize is that VS Code loves Typescript, and in this journey it will be your invaluable partner. For example, you can right click on the import and ask for the definitions, as shown in the screenshot below.

Using VS Code to navigate to the definitions

And that takes you to the central definitions file that lists all the components and their properties.

Just a few of the fascinating components in the AWS UI toolkit

Jackpot! Now I know what’s in there. But how to use it?

Getting The Layout Right

Right away what captured my eye was AppLayout because, really, there are two types of toys in a UI library; layout components and interactive components. And job number one is creating the layout, and job two is putting stuff in that layout.

Naming is important, right? AppLayout. Sounds good! I’m making an App, check. And I need a Layout, double check. AppLayout it is! It also helped that it was alphabetical and in the A's.

So I dropped an AppLayout on the page and right away I got a three column layout with a collapsible navigation panel to the left and a tools panel to the right, with a content section between. How did I know that? Because of the types!

The types for content, navigation and tools properties on the AppLayout component

So this is not only telling me what sections are available, but also the kind of content they are expecting, in this case ReactNode types which are, basically, anything renderable in React.

I replaced the entire contents of the canned App component with this code:

function App() {
  return (
    <AppLayout
      navigation={<div>Navigation</div>}
      content={<div>Content</div>}
      tools={<div>Tools</div>}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

Then I ran yarn start and right away I got a pretty decent looking responsive layout with three columns and collapsible sections. I was off to the races!

As Expected, With Exceptions

I’m not one to just play with components, I want to build something real-ish. So I created a Pokemon filter application. Some things, like Button were very straightforward.

<Button onClick={() => alert("hello!")}>Say Hello</Button>
Enter fullscreen mode Exit fullscreen mode

This worked out of the box, but the button itself wasn’t very visually appealing by default. Once again, Typescript to the rescue!

The potential variants of Button styling

Using Go To Definition in VSCode I was able to select a Button component and drill until I found the ButtonProps which showed me that there is a variant prop that I could use to select different styles of button. I ended up going with link.

Another moment came when I was working with the Input component, which, as you might guess is a text input. Everything was going great until I got to onChange where the event structure was a little different from what we expect.

Hinting on the event data from onChange

In this case event.target.value wasn’t there. Once again, VS Code to the rescue and I was able to find event.detail.value was the droid I was looking for instead.

Finding a New Pattern

Eventually I needed to put up a list of the Pokemon. I not only found a great Cards component to do that, I also found a great way of defining generic React components. Check this out!

Typescript generics for React components

So you give Cards an array of items and then you provide content functions that render the content for each item.

Anyway, because Typescript, the AWS team defined Card as a generic and when you pass an array in for that items property Typescript automatically infers the type of the array and then applies it to the other parts of the property definitions as required. In your content function you get type safety and hinting around the type from the array of items. And you don’t, as a consumer, need to do any additional work to make that happen. It just works, for free, just the way you’d expect it.

Seeing this was the most exciting moment of discovery on this journey. For some reason or another I hadn’t really thought about using generics for React components. So it was a genuine “Ah ha!” moment that I got from reading the code. This is not something I would have gotten from the documentation (most likely).

In addition to generics, seeing this pattern where you give the component some data and a render function (which is a pattern throughout the toolkit) was great to see. I’d seen it before in toolkits like Apple’s iOS List component. But I’ve rarely seen it on the web and I think it’s a good architectural pattern that’s worthy of more extensive use.

Video Version

If you want to see my exploration of the AWS UI toolkit for yourself check out the YouTube version.

Conclusion

The two big takeaways I learned from this sleuthing experience was:

  • Learn To Read Code  — Code is truth. And learning how to read someone else’s code can be a source of information, inspiration, education, all the good stuff. And what’s even better is that when you build that code reading muscle you can start to look at Github not just as a place to “grab code” but as the best code reading library the Universe has ever known.
  • Typescript Is Documentation  — Sure typing doesn’t answer all the questions. But it answers a lot of them very quickly, and it’s free. So the cost/benefit ratio is outstanding. Typescript is worth it, y’all.
  • Bonus: Naming Is Really Important  — I only scratched the surface on this library. There are tons of components. The only moments that I really struggled was with the naming on some of these components. For example; what’s a “Tile”? (Turns out it’s a radio button). Now that’s not really a fault of the folks at AWS. Naming is tough. But as frontend developers it would probably benefit us, at some point, to normalize what we name our UI elements, beyond Button.

Discussion (0)