Skip to content

Instantly share code, notes, and snippets.

@JulianKniephoff
Created May 9, 2022 13:55
Show Gist options
  • Save JulianKniephoff/31b3a45bc14bbcc1a1096878677ff757 to your computer and use it in GitHub Desktop.
Save JulianKniephoff/31b3a45bc14bbcc1a1096878677ff757 to your computer and use it in GitHub Desktop.
`checkAndEntail`
/**
* 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