1

I have function that creates instances of given class and I don't how to tell TypeScript that:
function builder returns instances of class passed in first argument

class A extends HTMLElement {
  color: 'white'
}

function builder<T extends typeof HTMLElement>(classParam: T) {
  let instance = new classParam()
  return instance
}

let instance = builder(A)
instance.color = 'black'
// Property 'color' does not exist on type 'HTMLElement'

Is it possible without using type assertion?

4
  • Is changing the signature of builder "allowed" ? Commented Jun 19, 2017 at 18:47
  • yes, you can change it Commented Jun 19, 2017 at 18:50
  • You can't new an HTMLElement though, I don't understand what it is you're trying to do. Are you looking for document.createElement() by any chance? Commented Jun 19, 2017 at 18:58
  • the code will later use document.createElement I have simplified the code Commented Jun 19, 2017 at 19:08

1 Answer 1

2

I've fixed and explained the problems:

class A extends HTMLElement {
  color: string = 'white' // you gave it the type "white", 
                          // but I assume you need the value "white" (and type `string`)
}


function builder<T extends HTMLElement>(classParam: { new(): T }) : T { 
  // previous line:
  // - `typeof` in the generic constraint is not valid
  // - the parameter could not be of type `T`, because you would not be 
  //   able to use `new`. It's now a parameter which has a constructor
  //    which creates a `T`
  // - we are now returning `T`, instead of (implicit) `any`
  let instance = new classParam()
  return instance
}

let instance = builder(A)
instance.color = 'black'

Link to playground

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

2 Comments

I got Type 'HTMLElement' is not assignable to type 'T', try it in TypeScript playground
I assumed your code was valid, but there where some mistakes. Fixed it and tested in the playground

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.