microsoft / microsoft/TypeScript

`ts-ignore`: Allow specifying maximum typescript version

Ouverte
#62,555 2 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Awaiting More Feedback Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

🔍 Search Terms

"ts-ignore", "version", "ts-expect-error"

✅ Viability Checklist
⭐ Suggestion

Allow @ts-ignore to specify the maximum version of typescript that it applies to.
Example:

// @ts-ignore version<4.0

Inequalities might also be worth implementing:

// @ts-ignore version>4.0
// @ts-ignore version!=4.0
📃 Motivating Example

This is inspired by the use case of ts-ignore detailed in the following article written by Evan Hahn:

https://evanhahn.com/ts-ignore-is-almost-always-the-worst-option/#the-once-edge-case-when-ts-ignore-might-be-optimal:~:text=The%20one%20edge,ts%2Dignore%20compelling.

For example, imagine you’re writing a library that supports old versions of TypeScript, before they added the unknown type. If you try to use unknown, you’ll get errors in old TypeScript versions but not new ones. @ts-ignore may be the right option here, because it’ll work in both versions (unlike the alternatives).

// Using `ts-expect-error`, this:
//   - fails on TS versions <3.9 (when `ts-expect-error` was introduced)
//   - works from versions 3.9 to <4.5
//   - fails for versions >=4.5 (when `Awaited`/`Promise` were introduced)
// @ts-expect-error
type A = Awaited<Promise<string>>;

// This works on all TS versions >=2.6 when `ts-ignore` was introduced:
// @ts-ignore 
type A = Awaited<Promise<string>>;

With this new extension to ts-ignore, library authors can get the type-safety of modern TypeScript without impacting users running older TS versions.

💻 Use Cases

What this helps with

For libraries supporting TS>=2.6 (when @ts-ignore was introduced), it allows using newer keywords without disabling TS on versions that support the new syntax:

// @ts-ignore version<3.0
const foo: unknown = {}

// @ts-ignore version<4.5
type A = Awaited<Promise<string>>;

Versions of TypeScript that support the ts-ignore but predate this new feature already just ignore the version specifier as if it were a comment. This ensures that no existing code will break.

What this does not help with

  • Libraries that have to support TypeScript versions predating @ts-ignore (<2.6).
  • New syntax that fails even when @ts-ignore is present. e.g.:
    • satisfies in versions < 4.9
    • template literal types in versions < 4.1
    • import type in versions < 3.8

Why not apply this to @ts-expect-error too?

Imagine you're writing a library which requires a TS version >=4.1.
You're personally developing on the latest version and it has the new feature introduced in 6.0.
You decide you want to use the v4.5 Awaited/Promise utility types but you know the people running TS 4.1 don't have them yet. You try out the new version specifier on @ts-expect-error. This happens:

// This
//   - works from versions 4.1 to <4.5 because the `ts-expect-error`
//   - fails for versions >=4.5 to <6.0 because it doesn't know to ignore those versions
//   - works for versions >=6.0 because it now correctly interprets the version tag
// @ts-expect-error version<4.1
type A = Awaited<Promise<string>>;

You end up making the problem worse instead of better 😖

This turns the @ts-expect-error version into a footgun for as long as people are commonly running TS versions that don't support the feature.

Related Issues

It seems there is a general appetite to have more nuanced control over ts-ignore and ts-expect-error.
It might be worth considering a syntax that allows for different flags.
Off the top of my head... Something based on JS object notation feels like it has potential: @ts-ignore-{}

// TS2322: Type 'string' is not assignable to type 'number'.

// @ts-ignore-{version: "<4.1", codes: ["TS2322"]}
const a: number = 'foo'

[!NOTE]
This could be used as an alternative to @ts-expect-error.
An unused expect error generates TS2578: Unused '@ts-expect-error' directive.
By not including TS2578 in the ignore codes, you replicate the effect of @ts-expect-error using the @ts-ignore-{} syntax.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

L’issue mentionne @ts-ignore et @ts-expect-error, mais n’identifie ni fichiers, ni tests, ni points d’entrée. Commencez par localiser la gestion de ces directives par le compilateur et examinez les issues associées pour comprendre le contexte de conception. Le travail terminé devrait inclure une syntaxe convenue pour les spécificateurs de version ainsi qu’un comportement pour les versions de TypeScript prises en charge et non prises en charge, avec des tests pour les inégalités proposées.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.