have the following service:
class ExperimentService {
//...
public __items: string;
public uploadExperiments<Payload extends Dictionary<ExperimentItemType[]>>(payload: Payload): asserts this is this & Record<"__items", keyof Payload> {
// ...
}
public getItem<Name extends typeof this.__items>(name: Name) {
// ...
}
}
const expirementService: ExperimentService = new ExperimentService();
expirementService.uploadExperiments({ mock: [...] });
expirementService.__items; // type mock
expirement.getItem; // getItem<Name extends string>() string is displayed, but it should be mock
is there any possibility to get dynamic types in getItem
method?
CodePudding user response:
You could add a type parameter to ExperimentService
that defaults to string
(to keep the current behavior) and that you can use when you assert the type of this
to change all places the type parameter is used:
class ExperimentService<K extends string = string> {
public __items!: K;
public uploadExperiments<Payload extends Dictionary<ExperimentItemType[]>>(payload: Payload):
asserts this is ExperimentService<keyof Payload & string> {
}
public getItem<Name extends K>(name: Name) {
}
}
const expirementService: ExperimentService = new ExperimentService();
expirementService.uploadExperiments({ mock: [""] });
expirementService.__items; // type mock
expirementService.getItem; // Names extends "mock"
You could also infer the type base on the type of the instance getItems
is getting called for, but this involves adding an extra type parameter to the function:
class ExperimentService {
public __items!: string;
public uploadExperiments<Payload extends Dictionary<ExperimentItemType[]>>(payload: Payload):
asserts this is this & Record<"__items", keyof Payload> {
}
public getItem<TThis extends ExperimentService, Name extends TThis['__items']>(this: TThis, name: Name) {
}
}
const expirementService: ExperimentService = new ExperimentService();
expirementService.uploadExperiments({ mock: [""] });
expirementService.__items; // type mock
expirementService.getItem("mock"); /// mock