通过 Array 在 TypeScript 中扩展只读元组类型

Extending readonly tuple types in TypeScript via Array

假设我有一个 Color 类型的定义以及它可接受的字符串值:

const COLORS = ["Q", "R", "G", "B"] as const;
type Color = typeof COLORS[number]; // "Q" | "R" | "G" | "B"

COLORS 的支持类型当然是 JavaScript 数组。我正在为数组的 includes 方法使用 polyfill,在 TypeScript 中声明如下:

interface Array<T> {
    includes(member: T, fromIndex?: number): boolean
}

现在,我明白了为什么 includesCOLORS 实例上不被识别为可用 — COLORSreadonly 而 [=14= 的声明中没有任何内容] 确保它不会改变任何东西。但是,有没有办法声明此 includes 方法,使其在 const/readonly 元组上可用?

总结以上评论:

你的 const 断言 as const 创建了一个 ReadonlyArray 类型,除了声明的 Array 接口之外,它还有自己的类型定义。因此,您也可以为 ReadonlyArray 添加全局扩充:

interface ReadonlyArray<T> {
    includes(searchElement: T, fromIndex?: number): boolean;
}

另一种方法是设置编译器选项 lib to include the built-in "es2016.array.include" API 声明。 lib 很有用,当你想以旧的 ES 版本为目标,但希望运行时也支持一些较新的语言结构,比如 array.prototype.includes,它可以被填充。在上面的编译器选项文档中,您还可以找到默认的 lib 设置,具体取决于您的 target:

► For --target ES5: DOM,ES5,ScriptHost
► For --target ES6: DOM,ES6,DOM.Iterable,ScriptHost

对于目标 ES5,您可以相应地扩展 tsconfig.json:

{
  "compilerOptions": {
    "target": "es5" ,
    // add es2016.array.include 
    "lib": ["es5", "dom", "scripthost", "es2016.array.include"]
    // ...
  }
}

PS:可以找到 TypeScript 库声明 here,或者如果您想查找它们,只需按住 Ctrl 单击 VS Code 中的类型即可。