Skip to content

Instantly share code, notes, and snippets.

@safareli
Created June 2, 2021 11:25
Show Gist options
  • Save safareli/73e833ca2dff84806f79e935b4b7e9c2 to your computer and use it in GitHub Desktop.
Save safareli/73e833ca2dff84806f79e935b4b7e9c2 to your computer and use it in GitHub Desktop.
type ABC = "A" | "B" | "C"
declare const ab: "A" | "B" | undefined
declare const isB: (value: ABC) => value is "B"
// both of this works fine
// const abnn1: "A" | "B" = assert_(ab,notUndefined)
// const abnn2: "A" | "B" = assert_(ab,and(notUndefined,notUndefined))
// but this doesn't
const b: "B" = assert_(
ab,
// infered type is:
// function and<
// "A" | "B" | undefined
// , "A" | "B" | undefined <---- here is error udefined shuold be removed
// , "B">
// ( f: (value: "A" | "B" | undefined) => value is "A" | "B" | undefined
// , g: (value: "A" | "B" | undefined) => value is "B"
// ): TypeGuard<...>
and(notUndefined, isB)
// ~~~
// because of incorectly infered type getting this error:
// Argument of type 'TypeGuard<ABC, "B">' is not assignable to parameter of type 'TypeGuard<"A" | "B" | undefined, "B">'.
// Type '"A" | "B" | undefined' is not assignable to type 'ABC'.
// Type 'undefined' is not assignable to type 'ABC'.(2345)
// if I specify type arguments it will work fine:
// and<"A" | "B" | undefined,"A" | "B","B">(notUndefined, isB)
)
// LIBRARY FUNCTIONS START HERE
/**
* `input` is not `undefined`
*/
export function notUndefined<T>(input: T | undefined): input is T {
return input !== undefined;
}
/**
* Combines multiple TypeGuards using `&&` operator
*/
export function and<I, O extends I, O2 extends O>(
f: (value: I) => value is O,
g: (value: O) => value is O2
): (value: I) => value is O2 {
return (value: I): value is O2 => f(value) && g(value);
}
export function assert(
condition: unknown
): asserts condition {
if (condition !== true) {
throw new Error("Assertion failed")
}
}
export function assert_<I, O extends I>(
value: I,
check: (value: I) => value is O,
): O {
assert(check(value));
return value;
}
@safareli
Copy link
Author

safareli commented Jun 2, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment