Non‑`void` returning assertion functions
See original GitHub issueSearch Terms
- assertion function non-void return type
- assertion function non-void return
- assertion function generic return
- assertion function custom return
Suggestion
A way to type a function that is both an assertion function and returning a value that is not void.
Use Cases
This is necessary to correctly type Jest’s expect(…)
matchers, which have a generic return type of R
.
Examples
declare const expect: <T>(actual: T): JestMatchers<T>;
type JestMatchers<T> = JestMatchersShape<
Matchers<void, T>,
Matchers<
Promise<void>,
T extends PromiseLike<infer U>
? U
: Exclude<T, PromiseLike<any>>
>
>;
type JestMatchersShape<TNonPromise extends {} = {}, TPromise extends {} = {}> = {
resolves: AndNot<TPromise>;
rejects: AndNot<TPromise>;
} & AndNot<TNonPromise>
type AndNot<T> = T & { not: T };
interface Matchers<R, T = {}> {
toBe<E>(expected: E): R & (asserts T is E);
}
declare const foo: unknown;
expect(foo).toBe("foo");
foo; // $ExpectType "foo"
// Some typings for engine262's Completion Record handling:
type UnwrapNormalCompletion<T>
= unknown extends T ? Value | undefined
: T extends NormalCompletion<infer V>
? (unknown extends V ? Value | undefined : V)
: T extends Completion ? never
: T;
/** @see https://tc39.es/ecma262/#sec-returnifabrupt */
export declare function ReturnIfAbrupt<T>(completion: T):
(UnwrapNormalCompletion<T>)
& (asserts completion is UnwrapNormalCompletion<T>);
/** @see https://tc39.es/ecma262/#sec-returnifabrupt-shorthands */
export { ReturnIfAbrupt as Q };
/**
* The type signature is the same, but `AssertNormalCompletion` causes an error to be thrown at runtime
* if `argument` is an AbruptCompletion, whereas `ReturnIfAbrupt` gets replaced with code that causes
* the caller to return the AbruptCompletion by engine262's build system:
*
* @see https://tc39.es/ecma262/#sec-returnifabrupt
* @see https://tc39.es/ecma262/#sec-returnifabrupt-shorthands
*/
declare function AssertNormalCompletion<T>(completion: T):
(UnwrapNormalCompletion<T>)
& (asserts completion is UnwrapNormalCompletion<T>);
export { AssertNormalCompletion as X };
Checklist
My suggestion meets these guidelines:
- This wouldn’t be a breaking change in existing TypeScript/JavaScript code
- This wouldn’t change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript’s Design Goals.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:74
- Comments:6 (1 by maintainers)
Top Results From Across the Web
V591. Non-void function must return value. - PVS-Studio
The analyzer has detected a non-void function with an execution path that does not return a value. Such a function results in undefined...
Read more >Warning: control reaches end of non-void function - Linux Hint
The non-void method contains the return type. Thus, the method wants to have a declaration that returns the items of the resultant type....
Read more >How to fix "error: control reaches end of non-void function"?
Assertions fire in debug builds; erroneous parameter value handled ... to return, then put an abort(); as the last line of your function....
Read more >Assertion functions in TypeScript - LogRocket Blog
Let's explore assertion functions in TypeScript and see how they can be used to express invariants on our variables.
Read more >Functions with (non-void) Return Types - UNC Comp 110
In functions that have non-void return types (dont worry, we'll cover "void" later), a value is returned by the function when we call...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Note that the duplicate #34636 (which got here first) has 39 👍 at the time of writing, and this one has only 9 👍. If these are used for prioritization, perhaps this one should be closed and the other should be reopened?
You miss the whole point of the post…
This can happen if you use val for something valid, then clean up some code below it that removes all the references to it, for example. You miss seeing its not necessary anymore because it tricks the linter. Whereas the assign pattern if I remove all references below I’ll clearly see it’s dangling.