I have a list of operations to a DB and every one of them have a different set of variables which need to be passed on, I figured it would be much easier to add new operations if I set the interfaces inside a list, like this, where if there is a match the function would require the correct interface for that operation:
const operation = {
add: 'example',
list: 'example2',
};
interface operationVariable {
add: { asset: string };
}
I'm trying to get the correct interface for each operation from a list like this:
function graphql<OP = keyof typeof operation>(request: OP, variables: operationVariable[OP], server = CONFIG.GRAPHQLSERVER) {
return post(server, request);
}
An error message comes up:
Type 'OP' cannot be used to index type 'operationVariable'.
Even if I remove the 'list' operation the error still persists...
How do I tell TypeScript to behave the way I want?
CodePudding user response:
Tell TypeScript that operation
is a record that uses keys of operationVariable
and holds strings:
const operation: Record<keyof operationVariable, string> = {
add: 'example',
list: 'example2', // error, not in operationVariable
};
Then the part you were missing is extends
. The extends
keyword is a generic constraint that you can use to tell TypeScript that this generic type must be a subtype of another type:
function graphql<
OP extends keyof typeof operation
// ^^^^^^^ OP is a keyof typeof operation
>(request: OP, variables: operationVariable[OP], // works
Here's how the handbook explains it.