Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: blog: Differences between linting and type checking #664

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

JoshuaKGoldberg
Copy link
Contributor

Prerequisites checklist

What is the purpose of this pull request?

Adds the blog post per #663.

What changes did you make? (Give an overview)

The post explains:

  1. The terminology difference between the two within "static analysis"
  2. Their differences in purpose: "can" vs. "should" 🧑‍🔬
  3. How linters are more granularly extensible with plugin rules
  4. Notes on their areas of overlap, with a suggestion to use linting only instead of TypeScript's noUnusedLocals and noUnusedParameters
  5. How linters and type checkers benefit from each other

In adding myself as an author, I noticed there wasn't yet support for Bluesky URLs. So I added that in too. I can split that out if preferred.

Related Issues

Fixes #663.

Is there anything you'd like reviewers to focus on?

  • Is this too long a post for its intended purpose of convincing folks that using ESLint with TypeScript is beneficial?
  • This title is not very emphatic - would it be better to go with a more punchy one? I'm drawing a blank.
  • On the other hand, I worry that the phrasing is a bit ... sales-y? for typescript-eslint. My personal biases might be showing 🙂.
  • I also commented some questions inline about whether we can visualize rich code blocks nicely

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for es-eslint ready!

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/es-eslint/deploys/67572cda25dfcc00087e42d0
😎 Deploy Preview https://deploy-preview-664--es-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for ja-eslint ready!

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/ja-eslint/deploys/67572cdafd9ae900072f7ace
😎 Deploy Preview https://deploy-preview-664--ja-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for new-eslint ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/new-eslint/deploys/67572cda50d900000836f031
😎 Deploy Preview https://deploy-preview-664--new-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

// ~~~~~~~~~~~~~~~~~~~~~~~~~
// eslint(jsx-a11y/alt-text):
// img elements must have an alt prop, either with meaningful text, or an empty string for decorative images.
```
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Question] Is there a preferred strategy for showing ESLint rule reports in code blocks within blog posts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have one, so I think this is fine.

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for hi-eslint ready!

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/hi-eslint/deploys/67572cdaf883170008d3c188
😎 Deploy Preview https://deploy-preview-664--hi-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for zh-hans-eslint ready!

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/zh-hans-eslint/deploys/67572cdabb38500008eb0836
😎 Deploy Preview https://deploy-preview-664--zh-hans-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for fr-eslint ready!

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/fr-eslint/deploys/67572cdad32e4b00082a8cb8
😎 Deploy Preview https://deploy-preview-664--fr-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for de-eslint ready!

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/de-eslint/deploys/67572cda6df1e60008ab2ade
😎 Deploy Preview https://deploy-preview-664--de-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Nov 26, 2024

Deploy Preview for pt-br-eslint ready!

Name Link
🔨 Latest commit cec8a69
🔍 Latest deploy log https://app.netlify.com/sites/pt-br-eslint/deploys/67572cda0ee8f90008e3606d
😎 Deploy Preview https://deploy-preview-664--pt-br-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

console.log("🍌");

// eslint(no-fallthrough):
// Expected a 'break' statement before 'case'.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love this first example:

  • It's pretty verbose
  • It doesn't show something that's clearly, definitely a valuable report ("what if I want to break through, that's too opinionated!")

...but I couldn't find a better lint rule that:

  • Produces clear valuable report on a likely bug
  • Is in js.configs.recommended
  • Isn't superseded by TypeScript

Seeking inputs on a better example to show!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-unused-vars? Although I guess TypeScript is now flagging that, too.

no-unexpected-multiline?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, and no-unexpected-multiline is pretty much made unnecessary by formatters... sigh

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I think this is fine to leave as-is.

Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran out of time so just left some comments on the first bits. Overall, I think we need to work on clearing up the language and the message. I'll continue looking tomorrow.

I'd also like to pull out adding support Bluesky social links into a separate PR as it's not really related to the article.

2. **Linters**: execute individually configurable checks known as "lint rules"
3. **Type checkers**: collect all files into a full understanding of the project

We'll focus in this blog post on *linters*, namely ESLint, and *type checkers*, namely [TypeScript](https://typescriptlang.org).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might want to expand this section a bit because both ESLint and TypeScript do more than one type of static analysis. For instance, ESLint also does scope analysis and code path analysis, while TypeScript does linting, scope analysis, and type checking.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 what would the benefit of that be? Now that the following section reports examples of each, what's the new info we'd want readers to know going in?

Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After taking another look at this, I see two areas of improvement for this post:

  1. You need to decide whether you are talking about linters and type checkers generically, or ESLint and TypeScript, specifically. My recommendation is update the intro to talk about ESLint and TypeScript, take a step back to talk about what static analysis is generically, then explain which types ESLint and TypeScript use, and then continue on the rest of the blog post specifically talking about ESLint and TypeScript.
  2. Make sure to include examples when you're describing abstract concepts. A lot of the verbiage around static analysis will be unfamiliar to most readers (including "type-safe"), so grounding those descriptions with concrete examples is important.

console.log("🍌");

// eslint(no-fallthrough):
// Expected a 'break' statement before 'case'.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-unused-vars? Although I guess TypeScript is now flagging that, too.

no-unexpected-multiline?

logUppercase(9001);
// ~~~~
// Argument of type 'number' is not assignable to parameter of type 'string'.
```
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Question] Is there a preferred strategy for showing TypeScript reports in code blocks within blog posts? (similar to the question about ESLint rule reports later on)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We haven't done this in blog posts before, so I think this approach is fine.

Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking a lot better. There is still some ambiguity over when we're talking about linters vs. ESLint itself, and I think we need to be careful about making claims about TypeScript does because it does more than just type checking.

Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left suggestions throughout to clean up wording, simplify phrasing, and add more detail where I thought it was missing.

A couple high-level comments to pull out:

  1. I think this is really more about using ESLint and TypeScript together rather than the differences between a linter and a type checker. I think the title should reflect that. I made edits where I thought this line was getting blurry.
  2. Please go back through and ensure each section follows the same sequence of discussing linting and then type checking. You start by always discussing linting first, but halfway through switch to discussing type checking first. Keeping this consistent will help the reader keep their bearings throughout.

---
layout: post
title: "Differences between linting and type checking"
teaser: "Linters such as ESLint and type checkers such as TypeScript catch different areas of code defects — and are best used in conjunction with each other."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
teaser: "Linters such as ESLint and type checkers such as TypeScript catch different areas of code defects and are best used in conjunction with each other."
teaser: "Linters such as ESLint and type checkers such as TypeScript catch different areas of code defects and are best used in conjunction with each other."

- Linting
---

If you're a JavaScript developer today, there's a good chance you're using ESLint and/or TypeScript to assist development.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you're a JavaScript developer today, there's a good chance you're using ESLint and/or TypeScript to assist development.
If you're a JavaScript developer today, there's a good chance you're using a combination of ESLint and TypeScript to assist development.

Comment on lines +14 to +19
Those two tools are common examples of their kind of tooling: ESLint is a common *linter*, whereas TypeScript is a common *type checker*.

Linters and type checkers are two kinds of tools that both analyze code and report on detected issues.
They may seem similar at first.
They both fall under the category of *static analysis*.
However, the two kinds of tools detect very different issues and are useful in different ways.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Those two tools are common examples of their kind of tooling: ESLint is a common *linter*, whereas TypeScript is a common *type checker*.
Linters and type checkers are two kinds of tools that both analyze code and report on detected issues.
They may seem similar at first.
They both fall under the category of *static analysis*.
However, the two kinds of tools detect very different issues and are useful in different ways.
These tools perform similar but different functions. ESLint is a *linter*, whereas TypeScript is a *type checker*.
Linters and type checkers are two kinds of *static analysis* tool that analyze code and report on detected issues. While they may seem similar at first, the linters and type checkers detect different categories of issues and are useful in different ways.
To understand these differences, it's first helpful to understand what static analysis is and why it's useful.

Many developers rely on static analysis to enforce consistent code formatting and style, to ensure code is well-documented, and to catch likely bugs.
Because static analysis runs on source code, it can suggest improvements in editors as code is written.

We'll focus in this blog post on ESLint and TypeScript:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We'll focus in this blog post on ESLint and TypeScript:
In this blog post, we'll focus on ESLint and TypeScript, and the different ways in which they perform static analysis.

Comment on lines +33 to +34
* **ESLint**: executes individually configurable checks known as "lint rules"
* **TypeScript**: collects all files into a full understanding of the project
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two bullets don't seem to fit into the flow of this paragraph. They aren't a compare-and-constract pair, so I'm not quite sure what the reader takeaway should be here. Some options:

If the takeaway is the context of the analysis, maybe something like this:

ESLint and TypeScript collect data about your code in different ways. Whereas ESLint executes on one file at a time without any knowledge of others files, TypeScript works by first scanning the entire project to make cross-file associations.

If the takeaway is how analysis is organized, maybe something like this:

ESLint's static analysis is organized as a series of individually configured lint rules. Because no two rules interact with one another, you can safely turn each rule on and off depending on your preferences. While TypeScript has some individually configured options, the majority of the analysis is performed in the type checking functionality.


### ESLint, With Type Information

Traditional lint rules run on a single file at a time and have no knowledge of other files in the project.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Traditional lint rules run on a single file at a time and have no knowledge of other files in the project.
Traditional ESLint rules run on a single file at a time and have no knowledge of other files in the project.

```

Augmenting ESLint with information from TypeScript makes for a more powerful set of lint rules.
See [Typed Linting: The Most Powerful TypeScript Linting Ever](https://typescript-eslint.io/blog/typed-linting) for more details on typed linting with typescript-eslint.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to make mention that type-aware linting has performance implications.

Augmenting ESLint with information from TypeScript makes for a more powerful set of lint rules.
See [Typed Linting: The Most Powerful TypeScript Linting Ever](https://typescript-eslint.io/blog/typed-linting) for more details on typed linting with typescript-eslint.

### TypeScript, With Linting
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### TypeScript, With Linting
### TypeScript with Linting


TypeScript adds extra complexity to JavaScript.
That complexity is often worth it, but any added complexity brings with it the potential for misuse.
Linters are useful for stopping developers from making TypeScript-specific blunders in code.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Linters are useful for stopping developers from making TypeScript-specific blunders in code.
ESLint is useful for stopping developers from making TypeScript-specific blunders in code.

Comment on lines +270 to +271
* TypeScripts checks that code is "type-safe": enforcing what you *can* write
* ESLint checks that code adheres to best practices and is consistent: enforcing what you *should* write
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* TypeScripts checks that code is "type-safe": enforcing what you *can* write
* ESLint checks that code adheres to best practices and is consistent: enforcing what you *should* write
* TypeScripts checks that code is "type-safe", enforcing what you *can* write.
* ESLint checks that code adheres to best practices and is consistent, enforcing what you *should* write.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Implementing
Development

Successfully merging this pull request may close these issues.

Blog post on why to use ESLint with TypeScript
3 participants