【问题标题】:Extending readonly tuple types in TypeScript via Array通过 Array 在 TypeScript 中扩展只读元组类型
【发布时间】:2019-09-13 10:57:20
【问题描述】:

假设我有一个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 并且 includes 的声明中没有任何内容可以确保它不会发生任何变异。但是,有没有办法声明这个 includes 方法,以便它在 const/readonly 元组上可用?

【问题讨论】:

  • 其实includes可以和只读数组一起使用!它在 TS lib.es2016.d.ts ReadonlyArray 接口中定义。您在 tsconfig.json 中设置了哪个目标,您是否调整了 lib 条目?
  • 是的,我实际上是故意针对 ES5 的。但实际上我发现我可以用 ReadonlyArray 而不是 Array 编写相同的接口声明。
  • 是的,polyfill 可能缺少只读数组类型。什么也有效:您可以在 tsconfig.json 编译器选项中指定 lib 属性以包含“es2016.array.include”,它为ReadonlyArray 提供类型。 "target": "es5", "lib": ["es5", "dom", "scripthost", "es2016.array.include"]
  • 哇,我不知道 "es2016.array.include" 可以列为库!我在哪里可以找到大型图书馆的详细子部分的列表?好的,但即便如此,我还是倾向于将扩展的 interface 声明保留在 polyfill 附近,在同一个文件中,以确保我不会突然得到一个没有另一个。
  • 您可以在compiler optionslib 条目中查看所有库配置。这完全符合您的目的,您 target 使用较旧的 ES 版本,但使用一些“较新”的 ES 库,这些库由一些 polyfill 填充。当然,您也可以自己编写全局增强,如果它只有一种方法,例如 array.prototype.includes(或者使用 polyfill 的内置类型,如果存在)。

标签: typescript extension-methods readonly


【解决方案1】:

总结上面的cmets:

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

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

另一种方法是设置编译器选项lib 以包含内置的"es2016.array.include" API 声明。 lib 很有用,当您想要针对较旧的 ES 版本,但希望运行时也支持一些较新的语言结构,例如 array.prototype.includes,这些结构可以是 polyfill。在上述编译器选项文档中,您还可以找到默认的 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 lib 声明可以在here 找到,或者如果您想查找它们,只需在 VS Code 中按 ctrl 单击类型即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 2022-12-03
    • 2021-02-07
    • 2021-10-17
    • 2015-12-10
    • 1970-01-01
    • 2019-01-15
    相关资源
    最近更新 更多