I've a function that tries to find a value in an array of numbers. The value can be either an object or a number. If the value is an object, there's a 'key' property that is used to get the number value from the object.
I'm trying to use Function Overloading to have a single function that can handle both cases.
type ObjectType = {
[key: string]: number
}
type FunctionType = {
<T extends ObjectType>(v: T, list: number[], key: string): T | undefined
(v: number, list: number[]): number | undefined
}
const find: FunctionType = <T extends ObjectType | number,>(v: T, list: number[], key?: string)=>{
const value = typeof v === 'number' ? v : v[key]
return list.find((item)=>{
return item === value
})
}
This creates an error Type undefined cannot be used as an index type
But in this branch, the value of v is an object, so how is key not defined?
Thank you
Edit
A solution was proposed by Alex Wayne, but it doesn't properly narrow value to a number.
If instead of calling list.find, we called a custom function that only accepts numbers, typescript would throw an error
const findNumber = (v: number, list: number[])=>{
/* Do stuff with v as a number */
return list.indexOf(v)
}
const find: FunctionType = <T extends ObjectType | number>(v: T, list: number[], key?: keyof T)=>{
const value = (key && typeof v === 'object') ? v[key] : v
return list[findNumber(value, list)]
}
Type 'ObjectType' is not assignable to type 'number'