Reputation: 33
I've been the whole day trying to figure this out I could not.
I want to create a class that uses a generic type in its constructor without passing it the type yet:
//Tool.ts
export type ToolMethod<T> = (x: number, y: number, obj?: T) => void
export class Tool<T extends HTMLElement> {
constructor(public element: T, public method: ToolMethod) {<-- /*Error here*/}
}
// or
export class Tool<T extends HTMLElement, U extends ToolMethod> {
constructor(public element: T, public method: U ){ /*Error ^ here too*/}
}
Because I want this:
//pencil.ts
const pencilElement = document.createElement('button')
const pencilMethod: ToolMethod<{/* some props */}> = (x,y, obj) => {
// ...
}
export const pencil = new Tool<HTMLButtonElement>(pencilElement, pencilMethod)
//or
export const pencil = new Tool<HTMLButtonElement, ToolMethod<{/*same props*/}>(pencilElement, pencilMethod)
I know that when I use a generic I have to pass a type, but I want to be able to specify that method
has to be a ToolMethod
without its type yet because the class still doesn't know it.
Like as <T extends HTMLElement>
, I'm able to select the specific element that tool will have, since not all elements share the same props.
Upvotes: 0
Views: 60
Reputation: 330316
Your Tool
class does need to be generic in two type parameters, but the second type parameter U
doesn't need to be a ToolMethod
itself; it could be the type parameter for ToolMethod
:
export class Tool<T extends HTMLElement, U> {
constructor(public element: T, public method: ToolMethod<U>) { }
}
Here, a Tool<T, U>
's method
is a ToolMethod<U>
. You can see it working:
const pencilMethod: ToolMethod<SomeProps> = (x, y, obj) => { }
export const pencil = new Tool(pencilElement, pencilMethod)
// const pencil: Tool<HTMLButtonElement, SomeProps>
pencil.element; // HTMLButtonElement
pencil.method; // ToolMethod<SomeProps>
Upvotes: 4
Reputation: 33111
I think You are looking for this:
// T is defined as function generic argument instead of type itself
export type ToolMethod = <T>(x: number, y: number, obj?: T) => void
export class Tool<T extends HTMLElement> {
constructor(public element: T, public method: ToolMethod) { // no error here anymore
}
}
You can define generic argument directly for function.
Upvotes: 0