This question is kinda difficult for me to explain and thus difficult for me to find a definitive answer for.
I have the below code:
type myType = {
apple ?: any
banana ?: any
}
const sample = function(myObject : myType) {
if (typeof myObject.apple !== 'undefined' || typeof myObject.banana !== 'undefined') {
// Do something
} else {
// This will cause an error!
}
}
sample({ apple: true }) // This is good
sample({ banana: 'hello world' }) // This is good
sample({ apple: false, banana: 'foo bar' }) // This is good
sample({}) // This is NOT good
sample({ banana: undefined }) // This is NOT good
sample({ taco: 'hello world' }) // This is NOT good
I am trying to make a type that can detect the "NOT good" cases
My Question: How can I modify myType
to trigger an error when all of its keys are not set but not when at least 1 of its known keys are set?
On a side note: I think I can do the below, but it seems very inelegant and probably a poor programming practice. I would prefer an alternate solution because my real code has dozens of keys and would be more than a little tedious.
type myType_1 = {
apple : any
banana ?: any
}
type myType_2 = {
apple ?: any
banana : any
}
type myType = myType_1 | myType_2
You can do this with a helper type: TS Playground
type OneOf<T> = {
[K in keyof T]-?: Pick<T, K> & Partial<T>
}[keyof T]
Note that for this to detect the sample({ banana: undefined })
case, the type of banana
must not be any
since undefined
is assignable to any
.