Jean-Philippe Pellet
Jean-Philippe Pellet

Reputation: 60006

Extending readonly tuple types in TypeScript via Array

Suppose I have this definition of a Color type as well as acceptable string values for it:

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

The backing type of COLORS is, of course, a JavaScript array. I am using a polyfill for the includes method of arrays, declared in TypeScript as follows:

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

Now, I get why includes is not recognized as available on the COLORS instance — COLORS is readonly and nothing in the declaration of includes ensures that it is not mutating anything. However, is there a way to declare this includes method such that it is available on const/readonly tuples?

Upvotes: 1

Views: 817

Answers (1)

ford04
ford04

Reputation: 74620

To summarize the comments above:

Your const assertion as const creates a ReadonlyArray type, which has its own type definitions besides the declared Array interface. So you could add the global augmentation for ReadonlyArray as well:

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

An alternative is to set the compiler option lib to include the built-in "es2016.array.include" API declarations. lib is useful, when you want to target an older ES version, but expect the runtime to also support some newer language constructs like array.prototype.includes, which could be polyfilled. In above compiler options docs, you also find the default lib settings depending on your target:

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

For target ES5, you can extend tsconfig.json accordingly:

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

PS: TypeScript lib declarations can be found here or simply by ctrl clicking on the type in VS Code, if you want to look them up.

Upvotes: 2

Related Questions