5

I have the type of a class like here as A_Type?

class A {
  constructor(public a: string) {}
}

type A_Type = {new (a: string): A}

And Id like to get the type of the instance of the A_Type constructor, so that I could type this function explicitly

class A {
  constructor(public a: number) {}
}
//                                              ** not working **
function f<W extends { new(a: number): A }>(e: W): instanceof W {
  return new e(2)
}

let w = f(A)

I am basically searching for the reverse operation of typeof in typescript.

1
  • How do you intend to extend it? Pass other classes to f? Commented May 5, 2020 at 22:06

3 Answers 3

6

You can use the built in InstanceType<T> utility to do this

class A {
    constructor(public a: number) { }
}

// declare that the return value of the class constructor returns an instance of that class
function f<W extends { new(a: number): InstanceType<W> }>(e: W) {
    return new e(2) // return type is automatically inferred to be InstanceType<W>
}

let w = f(A) // w: A

Playground link

Sign up to request clarification or add additional context in comments.

1 Comment

InstanceType<T> does not work with private constructor() because it can not infer the new () => R. Is there a way to get a reverse operation of typeof with a class withprivate constructor()?
1
function f<W extends { new(a: number): any }, R extends W extends { new(a: number): infer U } ? U : never>(e: W): R {
  return new e(2)
}

you need to use generics to extract the return type.

But if you always expect an instance of A you can simplify it to

function f<W extends { new(a: number): A }>(e: W): A {
  return new e(2)
}

6 Comments

this infers w as unknown
true, fixed, please verify.
Upvote, indeed it works (no idea how though). Can you explain in few words?
infer extracts nested types, so it says R is CONDITION ? VALUE_TRUE: VALUE_FALSE and condition is W is a constructor, then we return U otherwise never what makes R to be U.
A extends W extends {new (a: infer ARG): any} ? ARG : never - now A is number.
|
1

I would go with the following:

type Constructor<X> = {new (a: number): X}

function f<X>(e: Constructor<X>): X {
  return new e(2)
}

const w = f(A)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.