I'm trying to make an interface for my realm Database using typescript.
Basically I have an automation bot and I want to keep track of how people are using it and how much. For that I made some schemas that I want to add into an internal database and be able to recover information later.
So I made an interface for this realm database. The idea is that I provide what entity I want to add or recover and Typescript would give me the entity object as return type.
I defined the models of the entity objects as following:
export type AllEntitiesModel = {
copypastas: {
group: string;
requester: string;
};
googleSearches: {
group: string;
requester: string;
query: string;
};
};
And I've made an enum containing all my entity types:
export enum EntityTypes {
COPYPASTAS = 'copypastas',
GOOGLESEARCHES = 'googleSearches',
}
If I create a type like
type CopypastaModel = AllEntitiesModel[EntityTypes.COPYPASTAS];
It works, it knows that the CopypastaModel should be
copypastas: {
group: string;
requester: string;
};
What I'm trying to accomplish is to have a function that can do this but from the type of the argument I'm passing to it.
I would have a function with ideally this signature
function getAllEntities(entityType: EntityTypes) => AllEntitiesModel[entityType]
where this entityType is an argument that I pass to the function. In other words, I want typscript to know that if I call getAllEntities(EntityTypes.COPYPASTAS) I'm expecting it to return an object with type AllEntitiesModel.copypasta and if i call getAllEntities(EntityTypes.GOOGLESEARCHES) I'm expecting it to return an object with type AllEntitiesModel.googleSearch
I've tried a lot of things with no success. I have dug through the typescript documentation and found nothing like that. Any help is appreciated ;)
CodePudding user response:
You'll need to define generic type parameter restricted to allowed keys:
declare function getAllEntities<T extends keyof AllEntitiesModel>(entityType: T): AllEntitiesModel[T]
This allows Typescript to narrow return type according to provided key.
Here we use type argument inference — that is, we want the compiler to set the value of
Tfor us automatically based on the type of the argument we pass in
So for example in call getAllEntities(EntityTypes.COPYPASTAS) the type of T will be inferred as EntityTypes.COPYPASTAS (which is "copypastas") and return value type will be resolved to AllEntitiesModel["copypastas"].
