Skip to content

Turn assertions into type guards #2704

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

Merged
merged 1 commit into from
Mar 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export interface DeepEqualAssertion {
* Assert that `actual` is [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to
* `expected`, returning a boolean indicating whether the assertion passed.
*/
<ValueType = any>(actual: ValueType, expected: ValueType, message?: string): boolean;
<Actual, Expected extends Actual>(actual: Actual, expected: Expected, message?: string): actual is Expected;

/** Skip this assertion. */
skip(actual: any, expected: any, message?: string): void;
Expand All @@ -160,7 +160,7 @@ export interface LikeAssertion {
/**
* Assert that `value` is like `selector`, returning a boolean indicating whether the assertion passed.
*/
(value: any, selector: Record<string, any>, message?: string): boolean;
<Expected extends Record<string, any>>(value: any, selector: Expected, message?: string): value is Expected;

/** Skip this assertion. */
skip(value: any, selector: any, message?: string): void;
Expand All @@ -178,7 +178,7 @@ export interface FalseAssertion {
/**
* Assert that `actual` is strictly false, returning a boolean indicating whether the assertion passed.
*/
(actual: any, message?: string): boolean;
(actual: any, message?: string): actual is false;

/** Skip this assertion. */
skip(actual: any, message?: string): void;
Expand All @@ -201,7 +201,7 @@ export interface IsAssertion {
* value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) as `expected`,
* returning a boolean indicating whether the assertion passed.
*/
<ValueType = any>(actual: ValueType, expected: ValueType, message?: string): boolean;
<Actual, Expected extends Actual>(actual: Actual, expected: Expected, message?: string): actual is Expected;

/** Skip this assertion. */
skip(actual: any, expected: any, message?: string): void;
Expand All @@ -213,7 +213,7 @@ export interface NotAssertion {
* value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) as `expected`,
* returning a boolean indicating whether the assertion passed.
*/
<ValueType = any>(actual: ValueType, expected: ValueType, message?: string): boolean;
<Actual, Expected>(actual: Actual, expected: Expected, message?: string): boolean;

/** Skip this assertion. */
skip(actual: any, expected: any, message?: string): void;
Expand All @@ -224,7 +224,7 @@ export interface NotDeepEqualAssertion {
* Assert that `actual` is not [deeply equal](https://github.com/concordancejs/concordance#comparison-details) to
* `expected`, returning a boolean indicating whether the assertion passed.
*/
<ValueType = any>(actual: ValueType, expected: ValueType, message?: string): boolean;
<Actual, Expected>(actual: Actual, expected: Expected, message?: string): boolean;

/** Skip this assertion. */
skip(actual: any, expected: any, message?: string): void;
Expand Down Expand Up @@ -334,7 +334,7 @@ export interface TrueAssertion {
/**
* Assert that `actual` is strictly true, returning a boolean indicating whether the assertion passed.
*/
(actual: any, message?: string): boolean;
(actual: any, message?: string): actual is true;

/** Skip this assertion. */
skip(actual: any, message?: string): void;
Expand Down
40 changes: 40 additions & 0 deletions test-d/assertions-as-type-guards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {expectType} from 'tsd';
import test from '..';

type Expected = {foo: 'bar'};
const expected: Expected = {foo: 'bar'};

test('deepEqual', t => {
const actual: unknown = {};
if (t.deepEqual(actual, expected)) {
expectType<Expected>(actual);
}
});

test('like', t => {
const actual: unknown = {};
if (t.like(actual, expected)) {
expectType<Expected>(actual);
}
});

test('is', t => {
const actual: unknown = 2;
if (t.is(actual, 3 as const)) {
expectType<3>(actual);
}
});

test('false', t => {
const actual: unknown = true;
if (t.false(actual)) {
expectType<false>(actual);
}
});

test('true', t => {
const actual: unknown = false;
if (t.true(actual)) {
expectType<true>(actual);
}
});