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

Rule proposal: use satisfies over type annotation #6347

Closed
6 tasks done
jgoux opened this issue Jan 17, 2023 · 6 comments
Closed
6 tasks done

Rule proposal: use satisfies over type annotation #6347

jgoux opened this issue Jan 17, 2023 · 6 comments
Labels
package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin wontfix This will not be worked on

Comments

@jgoux
Copy link

jgoux commented Jan 17, 2023

Before You File a Proposal Please Confirm You Have Done The Following...

My proposal is suitable for this project

  • My proposal specifically checks TypeScript syntax, or it proposes a check that requires type information to be accurate.
  • My proposal is not a "formatting rule"; meaning it does not just enforce how code is formatted (whitespace, brace placement, etc).
  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Description

My rule would check that variables with type annotation should instead use the new satisfies operator.

Fail Cases

const setting: Setting = { color: "blue" };

Pass Cases

const setting = { color: "blue" } satisfies Setting;

Additional Info

Since satisfies is available it seems like its usage is often more correct than type annotation. Hopefully, typescript-eslint could help enforce its usage to have better type safety. 😄

@jgoux jgoux added enhancement: new plugin rule New rule request for eslint-plugin package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for maintainers to take a look labels Jan 17, 2023
@JoshuaKGoldberg
Copy link
Member

🤔 hmm. We generally try not to take in rules that ban swathes of TypeScript syntax. You can achieve this rule (minus auto-fixing) with no-restricted-syntax: https://typescript-eslint.io/play#ts=4.9.3&sourceType=module&showAST=es&code=MYewdgzgLgBBCmUoEswHMBcMDKiXpgF4YBvGUAGxACcsAiAIwoFd46YBfAbgCgg&eslintrc=N4KABGBEBOCuA2BTAzpAXGUEKQHYHsBaaFAF2gEsBjUxAE0OQE9dSBDAD3TAG1xsciaNHzRIAGn4DIANTaU2AIyQARRFXjy2pUWAB8YAJJ1ErCgDMKQnqSYAHRAEFcBdqQr5cAXUhSwX-gBfEECgA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA

{
  "rules": {
    "no-restricted-syntax": [
      "error",
      {
        "message": "Prefer using the satisfies operator, not explicit type annotations.",
        "selector": "VariableDeclarator > Identifier[typeAnnotation]"
      }
    ]
  }
}

I think we should leave this open for a little while and see if there's a lot of demand for it. You might consider publishing a standalone ESLint plugin with a custom rule if you want auto-fixing.

@bradzacher
Copy link
Member

it seems like its usage is often more correct than type annotation

Could you expand on what you mean here?
The only case I can think of when it is more correct is if you're making sure an object satisfies a record type.
Otherwise (unless I'm mistaken) there shouldn't be any difference between the two.

@jgoux
Copy link
Author

jgoux commented Jan 17, 2023

it seems like its usage is often more correct than type annotation

Could you expand on what you mean here? The only case I can think of when it is more correct is if you're making sure an object satisfies a record type. Otherwise (unless I'm mistaken) there shouldn't be any difference between the two.

Yes, the object satisfying a record type is the use case I have in mind. And as you said otherwise there is no difference, that's why I would prefer enforcing satisfied in my codebase over type annotation. 👍

@bradzacher
Copy link
Member

In that case - as Josh said - you can achieve this with no-restricted-syntax

https://typescript-eslint.io/linting/troubleshooting#how-can-i-ban-specific-language-feature

@bradzacher bradzacher closed this as not planned Won't fix, can't repro, duplicate, stale Jan 17, 2023
@bradzacher bradzacher added wontfix This will not be worked on and removed triage Waiting for maintainers to take a look enhancement: new plugin rule New rule request for eslint-plugin labels Jan 17, 2023
@bmish
Copy link
Contributor

bmish commented Jan 17, 2023

Just to spell out a bit more of the difference between them, satisfies allowed me to ensure a variable met my type requirements without losing the more-specific type information from the actual initialization in this example: bmish/eslint-doc-generator#249

@bradzacher
Copy link
Member

@bmish yes that's really the intended usecase of satisfies really - it allows you to validate that a type is assignable to some other type without coercing it to that type.

The motivating usecase for it was really to replace useless no-op generic functions people would use.

fuction asOptions<T extends Record<string, boolean>>(arg: T): T {
  return arg;
}

// bad as you lose the keys
const foo = {prop: true} as Record<string, boolean>;

// old style - Bad because useless fn call
const bar = asOptions({prop: true});

// new style - good - no runtime code for type check
const baz = {prop: true} satisfies Record<string, boolean>;

playground


To be clear - we're not saying that there aren't uses for satisfies - not at all! It's a great tool to be used in the right places.

Instead all we're saying is that we don't want to include rules that are simple syntax bans unless there's additional value we can add in the rule (like auto or suggestion fixers)

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

4 participants