2

I'm trying to create a function that takes two parameters, the first is the class reference and the second is a function with only one parameter that is an instance of the class reference and the output is a specific type. I tried the code below, but the typescript shows me an unknown type for p, even though I hope p was an instance of Pair.

interface Point{
    x: number
    y: number
}
class Pair{
    key = 0
    value = 0
}
function set<Class extends { new (): Type }, Type>(
    inputClass: Class,
    constructor: (o: Type) => Point) {
    //implementation...
}
set(Pair, p => ({x: p.key, y: p.value}))
// Typescript says:
// (parameter) p: unknown
// Object is of type 'unknown'.(2571)

I wanted the typescript to know that p must be an instance of Pair


I was able to implement using java generics, but I still can't replicate in typescript. Follow the code:

public <K extends Pair, T extends Class<K>> void setRenderer(T classe, Function<K, Point> constructor){
    //implementation
}

3 Answers 3

2

This should work:

function set<C>(
    inputClass: new ()=>C,
    constructor: (o: C) => Point) {
    //implementation...
}

Typescript Playground

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

Comments

1

Generics don't work like this, type inference doesn't go this way.

Simple solution:

interface Point{
    x: number
    y: number
}
class Pair{
    key = 0
    value = 0
}
declare function set<Type>(constructor: (o: Type) => Point): void;

set<Pair>(p => ({ x: p.key, y: p.value }))

Or if you really want to pass in the class:

interface Point{
    x: number
    y: number
}
class Pair{
    key = 0
    value = 0
}
function set<Type>(
    inputClass: { new (): Type },
    constructor: (o: Type) => Point) {
    //implementation...
}
set(Pair, p => ({ x: p.key, y: p.value }))

1 Comment

Thanks, the second way works for me. In that case, I really need the class as a parameter.
0

I'm not so sure why you need classes here.

You could achieve what you're looking for with interfaces, like this:

interface Point{
    x: number
    y: number
}

interface Pair{
    key:number
    value:number
}
const instance: Pair = {
    key : 0,
    value : 0
}

function set(value: Pair):Point {
    return  ({x: value.key, y: value.value})
}

Playground

Or if you really do want classes you can do the following:

Class Playground

2 Comments

Thanks for answering. But I need something more dynamic, something that I can infer from the class reference. My objective is to create a Map associating Classes and their respective builders. Something like new Map <T, (a: T) => Point>.
so T will vary? You may wish to update your question a little. Perhaps you are tying to do something like this? stackoverflow.com/questions/50774790/…

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.