I am trying to generate a d.ts
declaration file for my project.
There are two classes that do calculate heavy logic, and the remaining classes inherit from them. Properties on the subclasses are not defined on the object itself but rather on a getter
named defaults
within the class and defined in runtime.
Base Models
abstract class BaseModel {}
abstract class Model extends BaseModel {}
Inherited Model
class Example extends Model {
get defaults() {
return {
someProp: 1,
anotherProp: 2
}
}
}
My code works perfectly but there is no autocomplete for the dynamically added properties. I tried adding the following to the d.ts
file to make it aware of the dynamically properties but it didn't seem to work.
index.d.ts
class Model<T> extends BaseModel {
[P in keyof T]: T[P]
}
type ExampleType = {
someProp : number
anotherProp : number
}
class Example extends Model<ExampleType> {}
How can I add property definition to inherited classes without having to manually define them?
You can't do this directly, you can do it if you create the class using an extra function which will mutate the creating class to add the proeprties:
Note this uses the 3.0 feature Tuples in rest parameters and spread expressions for a 2.9, 2.8 version of
ReplaceInstanceType
see this answerWe can use this in one of two ways:
Use the output of
createModel
directly:This has the disadvantage that the extra fields are not usable from within the class itself, which may be an issue in some situation.
The second usage is to use
createModel
in the extends clause of the new class and only define the defaults in the class we pass to extends, adding extra methods in the outer class:This methods has the disadvantage of actually creating 2 classes the outer one which we actually use and the inner one we use to add the defaults property.
Edit
Since typescript actually does a very good job with strongly typing and validating key names you could also consider using
get/set
methods instead, you get good code completion and type validation but it is a bit more verbose: