Reputation: 60006
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
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