I'm writing function that'll return single value from object by key or return empty object if key does not exist.
Code:
//example data:
const obj = {
data: {test: 'word'},
str: 'Hi',
num: 22,
}
const pickOne = <T extends object>(obj: T, key: keyof typeof obj) => ((key in obj) ? obj.key : {})
console.log(pickOne(obj, 'data')) //should print {test: 'word'}
My problem is that I get this error: Property 'key' does not exist on type 'T'
.
I'm new to typescript but after reading docs I was sure that keyof typeof
would allow any key in obj
.
Any help would be appreciated, thanks.
CodePudding user response:
This:
obj.key
gets the property named "key"
on obj
, which may not exist.
Where this:
obj[key]
Gets the property name in the variable key
.
Which works without type error: See playground
CodePudding user response:
Your obj
has 3 keys:
data
str
num
When you write obj.key
you are telling the interpreter to find a key called key
, which does not exist.
On the other hand you can access these keys by its name using brackets:
const key = "data"
obj[key] // Should return {test: 'word'}
, which is equivalent to:obj["data"] // Should return {test: 'word'}
Moral of the story:
- The dot-notation is to access existing keys in a given object
- If the key exists it works. Otherwise, it errors out
- TypreScript also allows accessing these keys by name
- If the key exists it works. Otherwise, doesn't error out but returns
undefined
- If the key exists it works. Otherwise, doesn't error out but returns
Working example:
const obj = {
data: {test: 'word'},
str: 'Hi',
num: 22,
}
const key = "data"
console.log(obj[key])
console.log(obj["data"])
console.log(obj["key"])