Very basic example of what I’d like to do:
function extractStringValue<T extends object, K extends keyof T>(obj: T, key: K): string {
return obj[key]; // error: Type 'T[K]' is not assignable to type 'string'
}
// Desired usage
const myObj = { stringKey: "hi", boolKey: false }
const stringVal = extractStringValue(myObj, "stringKey"); // all OK
const stringVal2 = extractStringValue(myObj, "boolKey"); // should raise error
>Solution :
You should define T based on K. Since you want T[K] to be a string you have to change T to extend a Record<K, string>, since we don’t need anything else this definition is enough:
function extractStringValue<T extends Record<K, string>, K extends keyof T & string>(
obj: T,
key: K,
): string {
return obj[key];
}
Usage:
const myObj = { stringKey: 'hi', boolKey: false };
const stringVal = extractStringValue(myObj, 'stringKey'); // all OK
const stringVal2 = extractStringValue(myObj, 'boolKey'); // expected error