Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when trying to assign a subclass of a base class with generics to typeof of that base class #41770

Open
dummdidumm opened this issue Dec 2, 2020 · 4 comments
Labels
Bug A bug in TypeScript Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros
Milestone

Comments

@dummdidumm
Copy link

dummdidumm commented Dec 2, 2020

TypeScript Version: 4.1.2

Search Terms: class generic extends typeof 2322

I stumbled upon a type error when trying to assign a subclass of a base class with generics to typeof of that base class.

Code

declare class Base<T extends Record<string, any>> {
  a: T;

  constructor(a: T);
}

class Sub1 extends Base<{a: boolean}> {}

const error: typeof Base = Sub1;

// Silence error by adding another constructor definition:
declare class BaseWith2Constructors<T extends Record<string, any>> {
  a: T;

  constructor(a: T);
  constructor(a: T);
}

class Sub2 extends BaseWith2Constructors<{a: boolean}> {}

const noerror: typeof BaseWith2Constructors = Sub2;

Expected behavior:

I would expect the first assignment to not error as well.

Actual behavior:

I get error 2322. The error says Type 'T' is not assignable to type '{ a: boolean; }' and Property 'a' is missing in type 'Record<string, any>' but required in type '{ a: boolean; }' which sounds like the assignment checks are flipped.

Strangely enough, the error can be silenced by adding a second constructor definition. Is that a workaround I can rely on?

If this is expected behavior, how am I supposed to use the base class as common base in this example? I cannot do typeof Base<any> in this case because that's a syntax error.

Playground Link:

https://www.typescriptlang.org/play?ts=4.1.2#code/CYUwxgNghgTiAEkoGdnwEIpAHgCrxAA8AXEAO2DQCVwB7GYbZYmASzIHMAaeKMgTwB8g+AG8AsACh4vAFzxcAbilSZYWmWYwArmGL0AFFHm4AlMskBfFZKSp4AZW0AjAIwES5ShizZRx+GdaWggQPksRUWtJKXVNYgIYGHp5Yn4ABxBaADMfZAQAXkcXVwspAHpyx1ZQsjAEECT6QP5eYGB2Dl4yWmIAC0bEDS1dfRh4UGz2VmJWDVkpUCQ4RGh7THyAdRm+gCYAYWGWUfpkPA9SCmo6BiYWTp4+IUjVOQUy6SH4nT1DALMLGojj8xkYTOYpNFYms0E5nLsLl40BsQNt+gdgScYGd-PIgiEwmQImIobYjvAeo1kjBUhksrkUWi9odvli0EU4btFEA

Related Issues:

@typescript-bot typescript-bot added the Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros label Dec 2, 2020
@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Dec 2, 2020
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Dec 2, 2020
@RyanCavanaugh
Copy link
Member

These should both be errors -- new error({ a: "" }) is a legal invocation that puts a string where a boolean is expected.

@dummdidumm
Copy link
Author

Thanks for the quick reply, that makes sense. Is there a better way then to achieve what I want other than

class Genericbase extends Base<any> {}
const foo: typeof Genericbase = Sub

@RyanCavanaugh
Copy link
Member

There are other ways to do it, but that's probably the best one.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 13, 2022

👋 Hi, I'm the Repro bot. I can help narrow down and track compiler bugs across releases! This comment reflects the current state of the repro in the issue body running against the nightly TypeScript.


Issue body code block by @dummdidumm

❌ Failed: -

  • Type 'typeof Sub1' is not assignable to type 'typeof Base'. Types of construct signatures are incompatible. Type 'new (a: { a: boolean; }) => Sub1' is not assignable to type 'new >(a: T) => Base'. Types of parameters 'a' and 'a' are incompatible. Type 'T' is not assignable to type '{ a: boolean; }'. Property 'a' is missing in type 'Record' but required in type '{ a: boolean; }'.

Historical Information
Version Reproduction Outputs
4.2.2, 4.3.2, 4.4.2, 4.5.2, 4.6.2

❌ Failed: -

  • Type 'typeof Sub1' is not assignable to type 'typeof Base'. Types of construct signatures are incompatible. Type 'new (a: { a: boolean; }) => Sub1' is not assignable to type 'new <T extends Record<string, any>>(a: T) => Base<T>'. Types of parameters 'a' and 'a' are incompatible. Type 'T' is not assignable to type '{ a: boolean; }'. Property 'a' is missing in type 'Record<string, any>' but required in type '{ a: boolean; }'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros
Projects
None yet
Development

No branches or pull requests

3 participants