In TypeScript, is there any way to declare that a variable is a keyof
some Record
without knowing what the keys of the Record
are?
Assume an API response returns a payload of JSON. I want to define a type for the keys of the payload so I can index through the payload and know that the value will not be undefined. Is this possible or do I have to simply check for undefined every time I index the payload object?
Example:
const payload: Record<string, ValidValue> = await myApiCall()
const prop1 = 'a'
const prop2 = 'b'
if (isValidKey(prop1, payload)) {
const value1 = payload[prop1] // the type of `value1` should evaluate to `ValidValue`
}
const value2 = payload[prop2] // the type of `value2` should evaluate to `ValidValue | undefined`
I got it to work using a type guard function as well, but not returning key is keyof MyMap
. Instead, I had a type for the payload object of Record<string, ValidValue | undefined>
and then the type guard returns payload is Record<K, ValidValue>
where K
is the type of the key param.
You can play with it on TS Playground.
// Type alias for convenience
type Payload = Record<string, ValidValue | undefined>;
const payload: Payload = await myApiCall()
function isValidKey<K extends string>(key: K, payload: Payload): payload is Record<K, ValidValue> {
return key in payload;
}
const prop1 = 'a'
const prop2 = 'b'
if (isValidKey(prop1, payload)) {
const value1 = payload[prop1] // the type of `value1` should evaluate to `ValidValue` ✅
}
const value2 = payload[prop2] // the type of `value2` should evaluate to `ValidValue | undefined` ✅