Skip to content

[TS2.5 regression] generic type argument derivation with ": this" types #21117

Closed
@mprobst

Description

@mprobst

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.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions