Imagine having an interface structure like this:
export interface IHasIO {
inputs: {
[key: string]: string
},
outputs: {
[key: string]: string
}
}
The goal is to develop a function that adheres to this interface as a generic type and ensures that one of the output keys is provided as a parameter.
The desired outcome would be achieved with the following type definitions:
// extracting the 'outputs' property by indexing it.
export type Outputs<T extends IHasIO> = T['outputs'];
// restricting the function parameter to only allow keys present in the 'outputs'.
export type writeToOutput<T extends IHasIO> = (param: keyof Outputs<T>) => void;
However, when implementing a value that complies with the interface and using it as the generic argument, the parameter options are not properly restricted:
const instance: IHasIO = {
inputs: {},
outputs: {
a: 'someValue',
b: 'someOtherVal'
}
}
// defining a dummy function
const fn: writeToOutput<typeof instance> = (param) => {
}
// despite 'c' not being one of the output keys, it does not trigger TypeScript linting errors
fn("c");
// only these should work without any issues:
fn("a");
fn("b");
Why is this happening? What could be going wrong?