I developed a function that accepts an argument with two different architectures. I intentionally avoided enforcing rules to allow flexibility for the user, which is now causing me some headaches 😀. Oh well.
My goal is to verify if the entry has a function at the first level. For example:
// Function at the first level
const entry = {
data: 10,
upload:() => {},
otherData: {},
download: () => {}
}
// Function at a deep level
const entry = {
photo: {
total: 10,
upload: () => {}
},
videos: {
total: 10,
upload:() => {}
}
}
If TypeScript detects a function at the first level, I want it to return the type "slice", even if there are functions present in deeper levels. As soon as it finds a function at the first level, it should stop checking and return "slice".
If no function is found at the first level, it should return "group" without checking any further levels.
Note: The return value should be either slice
or group
, not a combination of both like slice | group
.
slice
should be returned if a function is found at the first level; otherwise, return group
.
The closest solution to passing all my test cases, except one, was to reverse my check like this:
type GetType<S, k = keyof S> = S[k & keyof S] extends Exclude<S[k & keyof S],Function> ? "group" : "slice"
It works fine but fails when an empty object property is encountered, returning group
:
// ❌ This fails and returns 'group' as the type. Expected type is 'slice'
const entry = {
data: {} // empty object,
upload: () => {}
}
// ✅ This works and returns 'slice' as expected
const entry = {
data: any value // empty object,
upload: () => {}
}
So, we need to find a way to exclude {}
, which leads to all the problems. Maybe I'm just tired and can't see clearly 😀. Anyway, I need a fresh perspective to help me out.