I have the following typescript code:
abstract class Parent {
static methods:Record<string,unknown>
static returnMethods () {
return this.methods
}
}
class Child extends Parent {
static methods = {
foo:(foo:string) => {
return 'foo ' foo
}
}
}
const test = Child.returnMethods()
test.foo('bar') //=> 'foo bar'
It works just like intended when i run it but VSCode shows me an error on the test.foo('bar')
method
unknown
This expression is not callable. Type '{}' has no call signatures.'.
and there is no Intellisense for the return of Child.returnMethods()
. I assume that a part of the problem is my typing of the methods
property in the parent class.
How do I type this example the right way and so that VSCode understands it? Or is there a different way to achieve a similar behavior?
CodePudding user response:
Typescript cannot assume that your methods
property does only consist of functions. You have defined the type unknown
which can be anything and is therefor not necessarly callable.
You could explicitly type all values in methods
to type of function:
static methods: Record < string, Function >
And the full code would work now without any ts errors:
abstract class Parent {
static methods: Record < string, Function >
static returnMethods() {
return this.methods
}
}
class Child extends Parent {
static methods = {
hello (hello: string) {
return 'hello ' hello
}
}
}
const test = Child.returnMethods()
test.hello('world') //=> 'hello world'
What is the idea behind having a method
property holding all class functions? Wouldn't you be better of by then completely removing the class and only creating a methods
object? .
CodePudding user response:
The problem is that you've said the properties in methods
have the type unknown
, which isn't callable.
For that specific example, you can define methods as
Record<string, (foo: string) => string>so that TypeScript knows that the properties on
methods` are callable:
abstract class Parent {
static methods: Record<string, (foo: string) => string>
// ...
}
That maintains type safety; you can't call the method with no arguments, or with a number
, it requires a string.
You could use Record<string, Function>
instead, which would lose type safety:
abstract class Parent {
static methods: Record<string, Function>
// ...
}
// ...
test.foo() //=> 'undefined bar' -- no type safety!