microsoft / microsoft/TypeScript

`ts-ignore`: Allow specifying maximum typescript version

未关闭
#62,555 2 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Awaiting More Feedback Suggestion
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
132

描述

🔍 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.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

该 issue 提到了 @ts-ignore 和 @ts-expect-error,但没有指出文件、测试或入口点。首先定位编译器处理这些指令的相关代码,并查看相关 issue 以了解设计背景。完成内容应包括一套达成一致的版本说明符语法,以及对受支持和不受支持的 TypeScript 版本的行为,并为所提议的不等式编写测试。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
compilers
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。