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
.