通过数组扩展TypeScript中的只读元组类型

时间:2019-09-13 10:57:20

标签: typescript extension-methods readonly

假设我具有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
}

现在,我明白了为什么includes实例上的COLORS不能被识别为可用– COLORSreadonly,并且includes的声明中没有任何内容可以确保它没有改变任何东西。但是,是否有一种方法可以声明此includes方法,以使其在const / readonly元组上可用?

1 个答案:

答案 0 :(得分:1)

总结以上评论:

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

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

另一种方法是将编译器选项lib设置为包括内置的"es2016.array.include" API声明。当您想定位较旧的ES版本时,lib很有用,但希望运行时还支持一些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:如果要查找它们,可以here或直接通过ctrl单击VS Code中的类型找到TypeScript库的声明。