arktype icon indicating copy to clipboard operation
arktype copied to clipboard

Introduce the true assertion method

Open acomagu opened this issue 7 months ago • 1 comments

Request a feature

From TypeScript 3.7, Assertion Function syntax is introduced.

declare function assertType<T>(v: unknown): asserts v is T;
declare const v: unknown;

assertType<string>(v);
// now v is considered string

This is similar to the assert method that already exists in arktype, though it doesn't need re-assignment to narrow type. I think this is more handy than the current assert method.

🤷 Motivation

Eliminates the need for new variables for types.

Current:

declare const value: unknown;
const typedValue = type(...).assert(value);

After this feature introduced:

declare const value: unknown;
type(...).newAssert(value);
// Here value is typed, no need for new variable.

💡 Solution

I think the best solution is to replace the current assert method to this behavior.

diff --git a/src/scopes/type.ts b/src/scopes/type.ts
index 356c513fc..77581c0ad 100644
--- a/src/scopes/type.ts
+++ b/src/scopes/type.ts
@@ -33,7 +33,7 @@ type TypeRoot<t = unknown> = evaluate<{
     infer: asOut<t>
     inferIn: asIn<t>
     allows: (data: unknown) => data is asIn<t>
-    assert: (data: unknown) => asOut<t>
+    assert: (data: unknown) => asserts data is asOut<t>
     node: Node
     flat: TraversalNode
     qualifiedName: QualifiedTypeName

But this is breaking change. IMO assert<T>(input: unknown): T is almost never more handy than assert<T>(input: unknown): asserts input is T(who would want reassignment?), so it's ideal to change the existing assert method to use the asserts syntax in the next beta release. However, if backward compatibility is a priority, choosing another name(for example, guard?) would also be a good idea.

Thanks.

acomagu avatar Jan 13 '24 09:01 acomagu