Description
🔎 Search Terms
interface method index accessor
method index type 'string'
🕗 Version & Regression Information
The bug occurs at the latest stable version published on npm. ts-loader
9.5.1
is also used in the project where this problem occurs.
The earlier versions have not been tested, but they are very likely to have the same behavior.
⏯ Playground Link
No response
💻 Code
export interface RawHeaders extends Record<Exclude <string, "get">, string[]> {
get(key: string): string[];
}
🙁 Actual behavior
The Record<Exclude<string, "somestring">, string[]>
type is being treated as a Record<string, string>
type, which causes following error message at the line where I declared the get
method:
Property 'get' of type '(key: string) => string[]' is not assignable to 'string' index type 'string[]'.
It also shows the same error message at the same line when using an index accessor without extending Record
:
export interface RawHeaders {
[k: Exclude<string, "get">]: string;
get(key: string): string[];
}
🙂 Expected behavior
It should not show any errors since the key get
is excluded when extending the Record
interface.
Additional information about the issue
I have not found any valid solutions that would allow a Record<string, nonAnyType>
interface to declare additional methods without making the value of the index accessor any
, which I believe most developers would not like since it makes the code unchecked, and so is hard to place documentations. This could also confuse new developers when making a library, since it loses the advantages of using TypeScript over plain JS.
Edit:
The solution of using an intersection type works, but I don't think this design to very logical, as in reality not all keys are allocated by a Record
like this. Furthermore built-in Object
functions accessible, and can coexist with the interface:
interface K {
[k: string]: string;
}
let d : K = Object.create(null);
d.toString();
whereas custom method declarations can only be a type
, which makes it un-extendable by another interface
, and un-implementable by a class
.