Open
Description
TypeScript Version: 3.1.1
Search Terms:
defines instance member property
Code
class A {
foo(): void {};
bar: number;
}
class B extends (A as { new(): Pick<A, Exclude<keyof A, "foo">> & Pick<A, "foo"> }) {
// (1)
foo(): void {
super.foo();
}
baz: number;
}
Expected behavior:
Compiles successfully
Actual behavior:
Error at (1): [ts] Class 'Pick<A, "bar"> & Pick<A, "foo">' defines instance member property 'foo', but extended class 'B' defines it as instance member function.
A more realistic example of this is when using https://github.com/bterlson/strict-event-emitter-types along with subclassing a superclass with overridable methods:
import StrictEventEmitter from "strict-event-emitter-types";
import * as inspector from "inspector";
interface SessionEvents {
"Runtime.executionContextCreated": (message: inspector.InspectorNotification<Runtime.ExecutionContextCreatedEventDataType>) => void
}
type StrictSession = StrictEventEmitter<inspector.Session, SessionEvents>;
class CustomSession extends (inspector.Session as { new (): StrictSession }) {
connect() { // error here
super.connect();
}
}
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
weswigham commentedon Oct 16, 2018
AFAIK, this is because non-homomorphic mapped types don't retain the methodiness origin of the key, hence the issue. We can probably fix this by either always allowing overrides of any properties from non-homomorphic mapped types or by trying to heuristically track the methodiness of a property symbol a bit more completely (similarly to how we track parameternameiness for tuple members). In any case, it should probably be possible to perform the override, since I think the conservative answer we give now gets a bit too much in the way when working with mapped types.
cherryblossom000 commentedon Apr 28, 2020
Mapped types keeping the methodiness would be useful for things like this:
(playground)
I also asked about this on SO.
jcalz commentedon Oct 7, 2020
Is there a useful workaround for this? I guess it's "manually write out your mapped types with method syntax" which is unfortunate.
ahoisl commentedon Jan 11, 2021
The workaround that worked for me is to declare the "method" as a readonly property returning a function:
nin-jin commentedon Jan 1, 2024
Minimal reproduction:
https://www.typescriptlang.org/play?#code/MYGwhgzhAECC0G8CwAoa7oDMD22AUAlIgL6qkqqiQwBC0ApgB4Au9AdgCYx6oZzSRE0NvQDuhAFzQACgEtgAawA8cADTQA5DmwboAPmjkiyNBm2Eh5YkA
Any ideas?
nin-jin commentedon Jan 2, 2024
Workaround:
https://www.typescriptlang.org/play?ssl=11&ssc=2&pln=1&pc=1#code/MYGwhgzhAECC0G8CwAoa7oDMD22AUAlIgL6qkqqiQwBC0ApgB4Au9AdgCYx6oZzSRE0NvQDuhAFzQACgEtgAawA8cADTQA5DmwboAPmjkiyNBgDm9ZllyFEvPhgBOlgK6O20QgF4DCcn3JiIA