I’m trying to access keys from an object via a function, and if the value doesn’t exist, check the next object. I understand the error, but I’m not sure how to handle this situation properly, for example allowing TS to access a missing property.
// constants with transformed values
const firstList = { foo: "a value" }
const secondList = { bar: "another value" }
function getValue( key: keyof typeof firstList | keyof typeof secondList ) {
let val = firstList[key]
if (val != undefined) return val
return secondList[key]
}
Element implicitly has an ‘any’ type because expression of type ‘"foo"
| "bar"’ can’t be used to index type ‘{ foo: string; }’. Property
‘bar’ does not exist on type ‘{ foo: string; }’.
>Solution :
Consider changing your implementation, and adding a type guard:
// check if key is in the value and narrows the type of `key`
function isKeyIn<K extends keyof T, T>(key: K, value: T): key is keyof T & K {
return key in value;
}
function getValue( key: keyof typeof firstList | keyof typeof secondList ) {
// if statement with early return would also work
return isKeyIn(key, firstList) ? firstList[key] : secondList[key];
}
See type predicates in the handbook.