Repository: TypeScript
Issue: Mixin expected argument type resolves to never when constrained to constructor of type whose property is typed via a type parameter
Labels: Needs Investigation

**TypeScript Version:**  3.8.0-dev.20191105

**Search Terms:** mixin 3.7 type

**Code**

```ts
import * as ts from "typescript";

type Constructor<T> = new (...args: any[]) => T;

export class Node<NodeType extends ts.Node = ts.Node> {
    compilerNode!: NodeType;
}

// BindingNamedNode
export interface BindingNamedNode {
    getName(): string;
}

export function BindingNamedNode<
    TCompilerNode extends ts.Node & { name: ts.BindingName; },
    TBase extends Constructor<Node<TCompilerNode>>
>(
    Base: TBase
): Constructor<BindingNamedNode> & TBase {
    return {} as any;
}

// InitializerableNode
export interface InitializerableNode {
    removeInitializer(): this;
}

export function InitializerableNode<
    TCompilerNode extends ts.Node & { initializer?: ts.Expression; },
    TBase extends Constructor<Node<TCompilerNode>>
>(
    Base: TBase
): Constructor<InitializerableNode> & TBase {
    return {} as any;
}

// BindingElement
export class BindingElement extends InitializerableNode(BindingNamedNode(Node))<ts.BindingElement> {
}
```

**Other Code**

Or my original code... I think it's more correct to do the above, but should either of these error?

```ts
import * as ts from "typescript";

type Constructor<T> = new (...args: any[]) => T;

export class Node<NodeType extends ts.Node = ts.Node> {
    compilerNode!: NodeType;
}

// BindingNamedNode
export type BindingNamedNodeExtensionType = Node<ts.Node & { name: ts.BindingName; }>;

export interface BindingNamedNode {
    getName(): string;
}

export function BindingNamedNode<T extends Constructor<BindingNamedNodeExtensionType>>(
    Base: T
): Constructor<BindingNamedNode> & T {
    return {} as any;
}

// InitializerableNode
export type InitializerableNodeExtensionType = Node<ts.Node & { initializer?: ts.Expression; }>;

export interface InitializerableNode {
    removeInitializer(): this;
}

export function InitializerableNode<T extends Constructor<InitializerableNodeExtensionType>>(
    Base: T
): Constructor<InitializerableNode> & T {
    return {} as any;
}

// BindingElement
export class BindingElement extends InitializerableNode(BindingNamedNode(Node))<ts.BindingElement> {
}
```

**Expected behavior:** No errors, as in TS < 3.7

[TS 3.6.3 Playground](https://www.typescriptlang.org/play/?ts=3.6.3#code/JYWwDg9gTgLgBAKjgQwM5xugZlCI4BEMAnmAKaoDGUwYMBA3ALABQrJ5cAwhAHaowoAV0oxoAHgAqAPjgBeOLzIB3OAAoAdFuRQA5qgBcKXsQDaAXQCU82ZOZsWZAB6RYcSgBs06AHIQAJmTifoGSpGRwzjBkvP7omBohEQoJSbIA3qxw2e54YMAeZFBJAIRGSWHk9gC+rKwA9PVwAELAsW26PsggZP5JrM6u8G3RUFjIlBGt7byd3b1JcJksOXC6ZDBdPWqWRgI0szV1ji7Q8FhCvKLAfC1t-h1bCwFBWTmSPOAFRYtRMXEYVCJF5wABkS0U8yMCWmD1mTwYcGqABo3tlJM00BE-rF0Dx+IIRGIoMEXlJPvlCsUXtJpKxpGo0S0sUYMVjWLtuHx9kSJLDHvM+jSwXA2agIstVlANkIoLwltUUOhkCYjg5GnAAJK8YAwYDIDzAABeRWQACNCv0TkM4CMiuNJlqdXqDcbTRayItJTlpSAIAA3Mja3X6w0mqA7aEAC2AqDVA1ObguVz1t2DLrD7stZKZHzy32pgUiTmiuMBwKL4PStudobdUAA-NCgQBRFzS1CoG68REo3OY8XF0sA-E80QSJLk-NUtJ0lgMpkDsispccoyjwnjknpuvh83ZwKycFiiVM6UwWXy9KKtDGYjxlga-mzFuFHq8GAJm2ebx3Ga6V8yHfeAcQBHdXT3D0kjUZ85h6IVAjUJJLEscQYXuDpAOAjJWGqIA)

**Actual behavior:**

```
TS2345: Argument of type 'typeof Node' is not assignable to parameter of type 'never'.

export class BindingElement extends InitializerableNode(BindingNamedNode(Node))<ts.BindingElement> {
                                                                         ~~~~
}
```

**Playground Link:** [TS 3.8.0-dev.20191105 Playground](https://www.typescriptlang.org/play/?ts=Nightly#code/JYWwDg9gTgLgBAKjgQwM5xugZlCI4BEMAnmAKaoDGUwYMBA3ALABQrJ5cAwhAHaowoAV0oxoAHgAqAPjgBeOLzIB3OAAoAdFuRQA5qgBcKXsQDaAXQCU82ZOZsWZAB6RYcSgBs06AHIQAJmTifoGSpGRwzjBkvP7omBohEQoJSbIA3qxw2e54YMAeZFBJAIRGSWHk9gC+rKwA9PVwAELAsW26PsggZP5JrM6u8G3RUFjIlBGt7byd3b1JcJksOXC6ZDBdPWqWRgI0szV1ji7Q8FhCvKLAfC1t-h1bCwFBWTmSPOAFRYtRMXEYVCJF5wABkS0U8yMCWmD1mTwYcGqABo3tlJM00BE-rF0Dx+IIRGIoMEXlJPvlCsUXtJpKxpGo0S0sUYMVjWLtuHx9kSJLDHvM+jSwXA2agIstVlANkIoLwltUUOhkCYjg5GnAAJK8YAwYDIDzAABeRWQACNCv0TkM4CMiuNJlqdXqDcbTRayItJTlpSAIAA3Mja3X6w0mqA7aEAC2AqDVA1ObguVz1t2DLrD7stZKZHzy32pgUiTmiuMBwKL4PStudobdUAA-NCgQBRFzS1CoG68REo3OY8XF0sA-E80QSJLk-NUtJ0lgMpkDsispccoyjwnjknpuvh83ZwKycFiiVM6UwWXy9KKtDGYjxlga-mzFuFHq8GAJm2ebx3Ga6V8yHfeAcQBHdXT3D0kjUZ85h6IVAjUJJLEscQYXuDpAOAjJWGqIA)

**Other Comments**

The issue does not occur when the type parameter is inlined ([Playground](https://www.typescriptlang.org/play/?ts=3.8.0-dev.20191105&ssl=1&ssc=1&pln=39&pc=2#code/JYWwDg9gTgLgBAKjgQwM5xugZlCI4BEMAnmAKaoDGUwYMBA3ALABQrJ5cAwhAHaowoAV0oxoAHgAqAPjgBeOLzIB3OAAoAdFuRQA5qgBcKXsQDaAXQCU82ZOZsWZAB6RYcSgBs06AHIQAJmRwAN6scOHueGDAHmRQfoEAhEahLBHpcMC8wDDAyB7AAF5xRpgaAKIuUBSowHz2GRG8yCBkpagaAEJZ-lm65bGtvDANEQC+9mOsrAD0M3DdvL28uj4tZP4JZKzOrvBZMHFYyJRBi8ur65sBQanpumQwa61qlkYCNCuT044u0PBYIS8UR1XgLHp9Z4bLbiMIRSSdNBBZyHJboHj8QQiMRQcRbaSsaRqOHhRGoNpwBFI1hvbh8D7YiTnSFXfFwABklLJtxJcGqMCEUDBwTGKHQyBM3wcczgAElsrl8kU4sgAEaxLY7P5uA5HE5BeU5PIFYpQNUam4hXnVEAQABuZENipNcVepQAFsBUFKtXs4IDgbk+HKFcblWb1WQYbyqeS4CiyGi6ZjhKIJPjCcS0hFuUZY9sWLSMQy07inWHTeaozdZJz81bs+F+YLhaK0MZiD6WDLmSsBmQhjBff93F5UOhe-1Bon4Amk+WlZXI1s1JOoddAmotpZrKkxkA)).

Also, I wouldn't be surprised if I was doing something wrong here, but this has worked in the past.

**Workaround**

Pass the class constructor into a function typed like so and the compile error goes away ([Playground](https://www.typescriptlang.org/play/?ts=3.8.0-dev.20191105&ssl=39&ssc=2&pln=38&pc=1#code/JYWwDg9gTgLgBAKjgQwM5xugZlCI4BEMAnmAKaoDGUwYMBA3ALABQrJ5cAwhAHaowoAV0oxoAHgAqAPjgBeOLzIB3OAAoAdFuRQA5qgBcKXsQDaAXQCU82ZOZsWZAB6RYcSgBs06AHIQAJmTifoGSpGRwzjBkvP7omBohEQoJSbIA3qxw2e54YMAeZFBJAIRGSWHk9gC+rKwA9PVwAELAsW26PsggZP5JrM6u8G3RUFjIlBGt7byd3b1JcJksOXC6ZDBdPWqWRgI0szV1ji7Q8FhCvKLAfC1t-h1bCwFBWTmSPOAFRYtRMXEYVCJF5wABkS0U8yMCWmD1mTwYcGqABo3tlJM00BE-rF0Dx+IIRGIoMEXlJPvlCsUXtJpKxpGo0S0sUYMVjWLtuHx9kSJLDHvM+jSwXA2agIstVlANkIoLwltUUOhkCYjg5GnAAJK8YAwYDIDzAABeRWQACNCv0TkM4CMiuNJlqdXqDcbTRayItJTlpSAIAA3Mja3X6w0mqA7aEAC2AqDVA1ObguVz1t2DLrD7stZKZHzy32pgUiTmiuMBwKL4PStudobdUAA-NCgQBRFzS1CoG68REo3OY8XF0sA-E80QSJLk-NUtJ0lgMpkDsispccoyjwnjknpuvh83ZwKycFiiVM6UwWXy9KKtDGYjxlga-mzFuFHq8GCsSjc+DUMjIaIl3kOApCHf54nCCAsDgNI1C3VlrDkWQd1dPcPSSNRnzmHohUCODiUsSx7EGM53C8Ts7hmXRXzId94BxAE-wAsglzUJJLHEGF7g6Gi6IyVhqiAA)):

```ts
const createBase = <T extends typeof Node>(ctor: T) => InitializerableNode(BindingNamedNode(ctor));
export class BindingElement extends createBase(Node)<ts.BindingElement> {
}
```