Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

248
Views
TypeScript generic function, unexpected behavior when generic is a class
class Class {
}
const f0 = <T extends typeof Class> (c:T): T => {
  return c
}
const call0 = f0 (Class) //ok

const f1 = <T extends typeof Class> (c:T): T => {
  const a = new c()
  return a //TS2322: Type 'Class' is not assignable to type 'T'.   'T' could be instantiated with an arbitrary type which could be unrelated to 'Class'.
}
const call1 = f1 (Class)

const f2 = <T extends typeof Class> (c:T):InstanceType<T> => {
  const a = new c()
  return a //TS2322: Type 'Class' is not assignable to type 'InstanceType '.
}
const call2 = f1 (Class)

TypeScript Playground

The argument is typed as T, so why isn't that acceptable for the return type?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Your first snippet doesn't make a lot of sense. It says that it takes something that is a constructor that returns a Class instance. That T extends new () => Class;

It also says it returns the same T (a constructor), but you are returning an instance; that doesn't make sense.

Solution

You were a lot closer in your second snippet

const f2 = <T extends typeof Class> (c:T): InstanceType<T> => {
  const a = new c()
  return a //TS2322: Type 'Class' is not assignable to type 'InstanceType '.
}

Again, typeof Class expands to {new() => Class} but what you really want is a generic constructor, so you can't just use typeof Class, you have to write your own type for the generic constructor of Class. Then your return type is a lot simpler.

class Class {  a = 1; }

class SubClass extends Class {  b = 2; }

class OtherClass {  c = 3; }

type ClassCtor<T extends Class> = new () => T;

const f = <C extends Class> (c: new() => C): C => {
  return new c();
}

// OR
const f = <C extends Class> (c: ClassCtor<C>): C => {
  return new c();
}



// It's a Class instance
const call1 = f(Class);

// It's a SubClass instance
const call2 = f(SubClass);

// Fails compilation
const call3 = f(OtherClass);

See live example

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!