-
Notifications
You must be signed in to change notification settings - Fork 12.8k
invariant
-style type guard
#19066
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I would expect the syntactic form of any such thing to be more like this: function invariant(condition: boolean, message: string): condition is true {
if (!condition) {
throw new Error(message);
}
return true;
} This doesn't work as you want it to (TS doesn't seem to infer from That said, I don't see a lot of advantages to using if (typeof a !== 'number') throw 'Sorry, strings not supported yet'; This will work exactly as you want function crash(message: string): never {
throw `Something crashed: ${message}.`;
}
function double(a: number | string) {
if (typeof a !== 'number') return crash('Sorry, strings not supported yet');
return a * 2;
} The project I work on uses this |
@RyanCavanaugh Thanks for the reference. Though I tried looking for existing issues, I could not find any that had the @krryan I hadn't thought about splitting the check and message formatting/post-processing etc. into a separate function. Thanks for the suggestion. I like your example of |
TypeScript Version: 2.5.3
(Playground)
Expected behavior:
invariant
should establish a type guard for the code following the invariant statement.Actual behavior:
TypeScript errors with
error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
This is because
a
still resolves to typestring | number
.Suggestion:
invariant
ensures that its first argumentcondition
is truthy, and throws otherwise, i.e. when the code following the invariant statement is reached it is safe to make all the same assumptions as if that code were wrapped inif (condition) { … }
, or equivalently, the invariant were replaced with its literal implementation.Although the latter works as a regular type guard (
if (typeof a !== 'number') { throw … }
), it makes the code unnecessarily verbose. I think there should be a way of declaring that a given function guarantees that some guard is active, and never returns otherwise, i.e. something like this (pseudo code):The text was updated successfully, but these errors were encountered: