Created
May 9, 2022 13:55
-
-
Save JulianKniephoff/31b3a45bc14bbcc1a1096878677ff757 to your computer and use it in GitHub Desktop.
`checkAndEntail`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Type guard for cases where one field of a structure determines | |
* the nullability of a selection of other fields. | |
* In the best case this will only check the `discriminator` field | |
* against the given `discriminant`, but you will also get a runtime error | |
* if any of the given `entailed` fields are `null`-ish when you don't | |
* expect them to be. | |
*/ | |
export function checkAndEntail<T, I extends keyof T, J extends keyof T>( | |
t: T, | |
discriminator: I, | |
discriminant: T[I], | |
entailed: [J], | |
): t is T & { | |
[K in keyof T]-?: NonNullable<T[K]>; | |
} { | |
if (t[discriminator] !== discriminant) { | |
return false; | |
} | |
return entailed.every(k => t[k] != null) || unreachable(); | |
} | |
// Where `unreachable` is something like | |
const unreachable = (msg?: string): never => { | |
throw new Error("unreachable"); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment