Closed
Description
TypeScript Version: Version 2.7.0-dev.20180110
Code
interface MsgConstructor<T extends Message> {
new(data: Array<{}>): T;
}
class Message {
clone(): this {
return this;
}
}
interface MessageList<T extends Message> extends Message {
methodOnMessageList(): T[];
}
function fetchMsg<V extends Message>(protoCtor: MsgConstructor<V>): V {
return null!;
}
class DataProvider<T extends Message, U extends MessageList<T>> {
constructor(
private readonly message: MsgConstructor<T>,
private readonly messageList: MsgConstructor<U>,
) {}
fetch() {
const messageList = fetchMsg(this.messageList);
messageList.methodOnMessageList();
}
}
Expected behavior:
Compiles, because V
is derived to be a subtype of MessageList
. This is what it did in TS 2.5.
Actual behavior:
With TS2.6, derivation works differently:
repro.ts(25,17): error TS2339: Property 'methodOnMessageList' does not exist on type 'Message'.
If you explicitly pass fetchMsg<U>(...)
, you can see why:
repro.ts(24,34): error TS2344: Type 'U' does not satisfy the constraint 'Message'.
Type 'MessageList<T>' is not assignable to type 'Message'.
Types of property 'clone' are incompatible.
Type '() => MessageList<T>' is not assignable to type '() => U'.
Type 'MessageList<T>' is not assignable to type 'U'.
This seems wrong - MessageList
inherits from Message
, so any MessageList
should satisfy the constraint Message
.