I am brand new to TS and have figured out a bunch, but I am having issues wrapping my head around how to do the following:
I am creating a Discord Bot template, which I will use for many different bots. A bot must have a Discord API key and app ID, but it could have additional API keys depending on internal functions, like perhaps accessing a weather API or logging API.
So, I want to create a standard object to attach to the bot; this object must have an API key and app ID, plus any additional key: value pairs. This is what I came up with for the object, seemed pretty basic:
/*
* A SecretsStore contains a discordAPIKey and a discordAPPID in addition
* to any additional secrets needed based on logger settings, etc.
*/
export type SecretsStore = {
[key: string]: string;
discordAPIKey: string;
discordAPPID: string;
};
Now, this is the part I am having difficulty figuring out. Secrets could be stored in several different management systems, and a bot would use one. For example, the secrets could be stored in the environment, config file, or Azure Key Vault. I want to define something like an abstract function, which enforces that the function must take an optional parameter containing additional API keys and return a SecretsStore object. The functions that "implement" this would do whatever they need to to get the secrets and create the SecretStore (ex: get the env variables or set up and access a vault). So I came up with this (a loader function may need additional options, like a key vailt ur, so the parameters need to account for requiring the one but allowing others.:
/*
* A SecretsStoreLoader defines a function that creates a SecretsStore
*/
export type SecretsStoreLoader = (options?: {
[key: string]: string | string[];
additionalKeys: string[];
}) => SecretsStore;
This is all good, but when I do something like the folowing, I get an error that the definitions do not match:
const loader: SecretsStoreLoader = (options?: {
azzureURL: 'test';
additionalKeys?: string[];
}) => {....}
And something like this gets no errors:
const loader: SecretsStoreLoader = () => {...}
So, I know I am not getting this right, and I think it is probably more fundamental and foundational than just the code I have made so far. I may also be overthinking this. But my ultimate goal is to ensure that any secrets loader must account for those possible optional keys. That way, the loader can be used in more than one bot implementation.
TLDR: can I define the shape of a function and specify that any implementing function must take a specific parameter but can have more parameters and return a specified object type?