Make assert, truthy and falsy typeguards
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
This commit is contained in:
parent
e58f466cc0
commit
e27183a9e8
3 changed files with 70 additions and 3 deletions
|
|
@ -4,6 +4,15 @@ import {expectType} from 'tsd';
|
|||
type Expected = {foo: 'bar'};
|
||||
const expected: Expected = {foo: 'bar'};
|
||||
|
||||
test('assert', t => {
|
||||
const actual = expected as Expected | undefined;
|
||||
if (t.truthy(actual)) {
|
||||
expectType<Expected>(actual);
|
||||
} else {
|
||||
expectType<undefined>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('deepEqual', t => {
|
||||
const actual: unknown = {};
|
||||
if (t.deepEqual(actual, expected)) {
|
||||
|
|
@ -32,9 +41,28 @@ test('false', t => {
|
|||
}
|
||||
});
|
||||
|
||||
test('falsy', t => {
|
||||
type Actual = Expected | undefined | false | 0 | '' | 0n;
|
||||
const actual = undefined as Actual;
|
||||
if (t.falsy(actual)) {
|
||||
expectType<Exclude<Actual, Expected>>(actual);
|
||||
} else {
|
||||
expectType<Expected>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('true', t => {
|
||||
const actual: unknown = false;
|
||||
if (t.true(actual)) {
|
||||
expectType<true>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('truthy', t => {
|
||||
const actual = expected as Expected | undefined;
|
||||
if (t.truthy(actual)) {
|
||||
expectType<Expected>(actual);
|
||||
} else {
|
||||
expectType<undefined>(actual);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,6 +5,15 @@ import test from '../../entrypoints/main.mjs';
|
|||
type Expected = {foo: 'bar'};
|
||||
const expected: Expected = {foo: 'bar'};
|
||||
|
||||
test('assert', t => {
|
||||
const actual = expected as Expected | undefined;
|
||||
if (t.truthy(actual)) {
|
||||
expectType<Expected>(actual);
|
||||
} else {
|
||||
expectType<undefined>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('deepEqual', t => {
|
||||
const actual: unknown = {};
|
||||
if (t.deepEqual(actual, expected)) {
|
||||
|
|
@ -33,9 +42,28 @@ test('false', t => {
|
|||
}
|
||||
});
|
||||
|
||||
test('falsy', t => {
|
||||
type Actual = Expected | undefined | false | 0 | '' | 0n;
|
||||
const actual = undefined as Actual;
|
||||
if (t.falsy(actual)) {
|
||||
expectType<Exclude<Actual, Expected>>(actual);
|
||||
} else {
|
||||
expectType<Expected>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('true', t => {
|
||||
const actual: unknown = false;
|
||||
if (t.true(actual)) {
|
||||
expectType<true>(actual);
|
||||
}
|
||||
});
|
||||
|
||||
test('truthy', t => {
|
||||
const actual = expected as Expected | undefined;
|
||||
if (t.truthy(actual)) {
|
||||
expectType<Expected>(actual);
|
||||
} else {
|
||||
expectType<undefined>(actual);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ export type Assertions = {
|
|||
/**
|
||||
* Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean
|
||||
* indicating whether the assertion passed.
|
||||
*
|
||||
* Note: An `else` clause using this as a type guard will be subtly incorrect for `string` and `number` types and will not give `0` or `''` as a potential value in an `else` clause.
|
||||
*/
|
||||
assert: AssertAssertion;
|
||||
|
||||
|
|
@ -121,16 +123,23 @@ export type Assertions = {
|
|||
/**
|
||||
* Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean
|
||||
* indicating whether the assertion passed.
|
||||
*
|
||||
* Note: An `else` clause using this as a type guard will be subtly incorrect for `string` and `number` types and will not give `0` or `''` as a potential value in an `else` clause.
|
||||
*/
|
||||
truthy: TruthyAssertion;
|
||||
};
|
||||
|
||||
type FalsyValue = false | 0 | 0n | '' | null | undefined;
|
||||
type Falsy<T> = T extends Exclude<T, FalsyValue> ? (T extends number | string | bigint ? T & FalsyValue : never) : T;
|
||||
|
||||
export type AssertAssertion = {
|
||||
/**
|
||||
* Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean
|
||||
* indicating whether the assertion passed.
|
||||
*
|
||||
* Note: An `else` clause using this as a type guard will be subtly incorrect for `string` and `number` types and will not give `0` or `''` as a potential value in an `else` clause.
|
||||
*/
|
||||
(actual: any, message?: string): boolean;
|
||||
<T>(actual: T, message?: string): actual is T extends Falsy<T> ? never : T;
|
||||
|
||||
/** Skip this assertion. */
|
||||
skip(actual: any, message?: string): void;
|
||||
|
|
@ -192,7 +201,7 @@ export type FalsyAssertion = {
|
|||
* Assert that `actual` is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy), returning a boolean
|
||||
* indicating whether the assertion passed.
|
||||
*/
|
||||
(actual: any, message?: string): boolean;
|
||||
<T>(actual: T, message?: string): actual is Falsy<T>;
|
||||
|
||||
/** Skip this assertion. */
|
||||
skip(actual: any, message?: string): void;
|
||||
|
|
@ -336,8 +345,10 @@ export type TruthyAssertion = {
|
|||
/**
|
||||
* Assert that `actual` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), returning a boolean
|
||||
* indicating whether the assertion passed.
|
||||
*
|
||||
* Note: An `else` clause using this as a type guard will be subtly incorrect for `string` and `number` types and will not give `0` or `''` as a potential value in an `else` clause.
|
||||
*/
|
||||
(actual: any, message?: string): boolean;
|
||||
<T>(actual: T, message?: string): actual is T extends Falsy<T> ? never : T;
|
||||
|
||||
/** Skip this assertion. */
|
||||
skip(actual: any, message?: string): void;
|
||||
|
|
|
|||
Loading…
Reference in a new issue