Dave's Notebook

AI Tips for TypeScript Development

Introduction

There is a lot of noise on the Internet regarding the use of AI tools in software development. Some say it’s the future, while others are skeptical about its effectiveness. As you’ll quickly ascertain from this article, I believe AI can be a powerful ally when used correctly.

While this article will focus on TypeScript development, many of the tips can be applied to other programming languages as well. So, don’t ignore this article just because you don’t use TypeScript. In my career, I’ve used everything from C/C++, Java, C#, JavaScript, TypeScript, Scala, and F# and I could apply each of these tips to any of those languages and associated frameworks.

Developer Focused

While this article is not intended to be an argument for hiring a developer over using AI tools to write code as someone who has never written code before, this article is developer focused. I don’t want to say you can’t use AI tools effectively if you aren’t a developer but I can assure you that your chances of success go up dramatically if you are a developer or use a developer to help you.

Summary Thesis

My summary thesis is that the AI tools are just another programming language that we can use to write code faster. However, like any programming language, it isn’t a silver bullet any more than when any other programming language, framework, library, or methodology is introduced.

When we approach the use of AI tools as just another programming language, we can start to see how the effective use of these tools depends on our ability to apply software development best practices to the use of these tools.

As many others have written about how to prompt your AI tool of choice, I’m going to focus more on best practices that go beyond AI frameworks or prompting practices. If you were looking for that information, you should look elsewhere.

In short, the best way to use AI tools effectively is to use all the best practices of software development that you should have been using all along. Only now these practices are more critical to you success because your AI tool, at least currently, is only as good as the best practices you apply to your software development process.

So, in no particular order, here is what you need to be successful using AI as your development partner.

AI Frameworks

There are several AI frameworks available, including The BMad Method, Spec-kit, OpenSpec and AgentOS. The one I use is the BMad Method, which follows an Agile/Scrum workflow. So, when I talk about stories later on, I’m referring to stories like you would find in an Agile/Scrum process.

Back to AI frameworks…

Each has advantages and disadvantages. The important thing is that they help you think through what it is you intend to accomplish with your software development effort. If you haven’t already picked one, I would encourage you to do so because it is the only way you’ll be able to write any significant software using AI tools.

To be clear, when all I need is a short utility script, I don’t bother using the BMad Method, I just describe the utility and let ‘er rip. But for anything more significant, like the Dividend-based trade management application I’m writing, I use the BMad Method to help me think through what I’m trying to accomplish.

Review the Stories

Once your AI framework has generated the stories for you, or whatever specs it is going to use to write your code, review them carefully. Make sure they accurately describe what you want to accomplish. If they don’t, modify them or have the AI tool try again until they do.

Remember, your stories are essentially teaching the AI how to write your application. If the stories are wrong or unclear, the code generated by the AI tool won’t be accurate and you’ll end up being one of those developers complaining about how AI tools don’t work.

In the case of the BMad Method, it first generates Epics and then generates Stories for each Epic. I recommend reviewing the Epics prior to generating the Stories to ensure the Epics accurately describe what you want to accomplish. Once the Epics are correct, then generate the Stories and review them as well.

Test-Driven Development (TDD)

I’ve argued for test driven development for years even if I’ve had trouble convincing my managers of the practice. But when I started using AI to develop software, I quickly realized that TDD was no longer optional. It was critical to ensuring that the code that gets generated by the AI tool is, in fact, what I had in mind. To be clear, it doesn’t guarantee that the code is correct, it just makes it a lot more likely that it will be.

I first discovered this while writing eslint rules using AI. Since writing tests for eslint rules is relatively easy and example based, I could write tests that describe what my lint rule was supposed to do. Then, I could explain to the AI tool what the lint rule was supposed to do and have it fill in any edge cases I might have made in my initial set of tests. Finally, I could prompt AI to then implement the lint rule to satisfy the tests. This process worked so well that now, every story I write for the AI to implement includes a TDD section.

End to End Tests

If you are familiar with the testing pyramid, you know that the rule of thumb is to have more unit tests than integration tests and more integration tests than end to end tests. However, when using AI tools, your end to end tests become your QA department so you’ll want as many end to end tests as it takes to ensure things you worked in in the past don’t drift as you add new features. AI has a bad habit of forgetting that the code you wrote that applies to X feature from last week when you are working on Y feature this week. End to end tests help you catch these issues before they make it to production.

UI Tests

While we are talking about tests, we don’t want to forget User Interface (UI) tests. Even if text based, most applications have a UI. Some way for the user to interact with the application. If your application has a UI, you’ll want to make sure you have UI tests to ensure that the UI works as expected and doesn’t change as your code changes without your knowledge and approval. AI tools are good at generating code but they are not so good at understanding how users interact with the UI. So, you’ll want to make sure you have UI tests to ensure that the UI works as expected.

One popular tool for UI regression testing in the TypeScript/JavaScript ecosystem is StoryBook. With the right plugins, you can have it create snapshots for all the different ways a component might be rendered. If the snapshot changes, your tests will fail and you’ll be alerted to the change. This is a great way to ensure that your UI doesn’t change unexpectedly as you add new features or modify existing ones.

If you setup StoryBook at the beginning of your project, you can even mock your data so that you can effectively use StoryBook as a way to snapshot entire pages of your application instead of just a single component. This can be a very powerful safeguard and one I’m sorry I haven’t implemented sooner in my own projects.

Code Reviews

While code reviews are important when working with a group of developers, they become critical when those “other developers” are your AI tools.

First, your stories should be short enough that you can implement the story in a small number of file changes. Ideally no more than 10 files changed with no more than 200 lines of code changed. This makes it easier to review the changes made by the AI tool.

When you review the code, just like you would do with a human developer, make sure the code meets your standards for quality, readability, and maintainability. If it doesn’t, don’t be afraid to reject the changes and have the AI tool try again. Remember, you are the boss. The AI tool is just a tool to help you get your job done faster.

Also, make sure you understand the changes made by the AI tool. Does it look like code you would have written? Can you explain it to someone else? If not, you might want to have the AI tool try again or at least make sure you understand why it made the changes it did.

One thing to watch out for is when your AI tool does something like overriding lint rules. Make sure there is a good reason for doing so and that it is documented with a comment in the code. You have the responsibility to challenge the AI tool whenever you think it has done something incorrectly.

Finally, don’t be afraid to refactor the code generated by the AI tool. Just because the AI tool wrote it doesn’t mean it’s perfect. You are still responsible for the quality of the code in your codebase.

Duplicate Code Checks

Another important code review practice is to check for duplicate code. AI tools can sometimes generate code that is similar to existing code in your codebase. This can lead to maintenance issues down the road. So, make sure you check for duplicate code and refactor it as necessary. The tool I use for this is jscpd (JS Copy/Paste Detector). It can scan your codebase for duplicate code and report any issues it finds.

Not all duplicate code is bad. Sometimes, duplication is necessary for performance or other reasons. But, in general, you want to minimize duplicate code in your codebase so that when you fix a bug or add a feature in one place, every place where it applies gets that change.

Automated Code Reviews

There are several products on the market that use AI to review your code. Some of these products can be integrated into your CI/CD pipeline to automatically review code changes made by the AI tool. This can help you catch issues early and ensure that the code meets your standards for quality, readability, and maintainability. One such tool that I use is CodeRabbit. It integrates with GitHub and can automatically review pull requests for code quality issues. It can also be configured to enforce coding standards and best practices.

Related to this, there are several static analysis tools that can help you identify potential issues in your code. These tools can be used in conjunction with AI tools to ensure that the code generated by the AI tool is of high quality. Two TypeScript-friendly examples are SonarQube and ESLint. You can checkout my SmartNgRX project for an example of pretty strict ESLint rules for TypeScript development.

Visual Testing

Finally, you should at least review as much of the application visually as possible. While automated tests are great, they can’t catch everything. There are some things that only a human can catch by looking at the application. So, make sure you take the time to review the application visually to ensure that everything looks and works as expected.

Applying This Advice as a non-Developer

If you are not a developer, you can still apply most of this advice by asking the AI for help. For example, you can ask AI what the best practices are for writing tests for your application and have it set that up. You can also ask it what tools are generally used to ensure code quality and have it set those up as well.

The point is to not just blindly accept the code generated by the AI tool. You need to take an active role in ensuring that the code meets your standards for quality, readability, and maintainability. By applying these best practices, you can ensure that your AI generated code is of high quality and meets your needs.

If you don’t have standards for quality, readability, and maintainability, you’ll need to get help either from AI or a developer with experience. One developer with more than 10 years of experience following these rules can help you avoid a lot of pitfalls that can easily cost you more time and money in the long run.