Raphael Castro
Raphael Castro

Reputation: 1148

How can I set the type of every property in a class to a function signature in typescript?

I am using a class to contain all methods related to the functionality of a class. This means that all the methods of this class need to have a specific signature I am trying to use an index signature like so:

interface rulesType {
    [key:string]: testFn
}

however when I try to use this typescript complains that " class 'rules incorrectly implements interface 'rulesType'"

class rules implements rulesType {
    test() {
        
    }
}

so sorry here is the interface for testFn:

type testFn = () => void

Why?

Upvotes: 1

Views: 91

Answers (1)

Tadhg McDonald-Jensen
Tadhg McDonald-Jensen

Reputation: 21474

class rules implements Record<keyof rules, ()=>void> {
    test() {
        
    }
}

with just [key:string]: testFn it is indicating that every possible string key will be a function, but your class has a finite amount of keys.

You can circularly refer to the keys of your own class in implemented interfaces, so Record<keyof OWN_CLASS, testFn> will be the constraining type you are looking for.

Note that in typescript a function that returns anything is assignable to a function that returns void so you won't have much help constraining return type:

class rules implements Record<keyof rules, ()=>void> {
    test() {
        return "not void" // doesn't error
    }
}

To do proper constraint so that the return type is always void you can get a little more funky:

type AllFuncs<Cls> = {
    [K in keyof Cls]: Cls[K] extends () => infer R
        ? R extends void
            ? testFn // if the return type is void, no problem
            : () => undefined // the return type isn't void, must be undefined.
        : testFn; // isn't a function, set constraint to function for error.
};
class rules implements AllFuncs<rules> {
    test() {
        return "now is error :)"
    }
}

Upvotes: 3

Related Questions