Skip to content
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

Add missing If types for Is types #961

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export type {
NonNegativeInteger,
IsNegative,
} from './source/numeric';
export type {IfNegative} from './source/if-negative';
export type {GreaterThan} from './source/greater-than';
export type {GreaterThanOrEqual} from './source/greater-than-or-equal';
export type {LessThan} from './source/less-than';
Expand All @@ -102,18 +103,28 @@ export type {WritableKeysOf} from './source/writable-keys-of';
export type {HasWritableKeys} from './source/has-writable-keys';
export type {Spread} from './source/spread';
export type {IsInteger} from './source/is-integer';
export type {IfInteger} from './source/if-integer';
export type {IsFloat} from './source/is-float';
export type {IfFloat} from './source/if-float';
export type {TupleToUnion} from './source/tuple-to-union';
export type {UnionToTuple} from './source/union-to-tuple';
export type {IntRange} from './source/int-range';
export type {IsEqual} from './source/is-equal';
export type {IfEqual} from './source/if-equal';
export type {
IsLiteral,
IsStringLiteral,
IsNumericLiteral,
IsBooleanLiteral,
IsSymbolLiteral,
} from './source/is-literal';
export type {
IfLiteral,
IfStringLiteral,
IfNumericLiteral,
IfBooleanLiteral,
IfSymbolLiteral,
} from './source/if-literal';
export type {IsAny} from './source/is-any';
export type {IfAny} from './source/if-any';
export type {IsNever} from './source/is-never';
Expand Down
18 changes: 9 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Click the type names for complete docs.
- [`WritableKeysOf`](source/writable-keys-of.d.ts) - Extract all writable (non-readonly) keys from the given type.
- [`HasWritableKeys`](source/has-writable-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any writable fields.
- [`Spread`](source/spread.d.ts) - Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.
- [`IsEqual`](source/is-equal.d.ts) - Returns a boolean for whether the two given types are equal.
- [`IsEqual`](source/is-equal.d.ts) - Returns a boolean for whether the two given types are equal. (Conditional version: [`IfEqual`](source/if-equal.d.ts))
- [`TaggedUnion`](source/tagged-union.d.ts) - Create a union of types that share a common discriminant property.
- [`IntRange`](source/int-range.d.ts) - Generate a union of numbers.
- [`ArrayIndices`](source/array-indices.d.ts) - Provides valid indices for a constant array or tuple.
Expand Down Expand Up @@ -233,11 +233,11 @@ type ShouldBeNever = IfAny<'not any', 'not never', 'never'>;
//=> 'never'
```

- [`IsLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
- [`IsStringLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
- [`IsNumericLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
- [`IsBooleanLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
- [`IsSymbolLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
- [`IsLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). (Conditional version: [`IfLiteral`](source/if-literal.d.ts))
- [`IsStringLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). (Conditional version: [`IfStringLiteral`](source/if-literal.d.ts))
- [`IsNumericLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). (Conditional version: [`IfNumericLiteral`](source/if-literal.d.ts))
- [`IsBooleanLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). (Conditional version: [`IfBooleanLiteral`](source/if-literal.d.ts))
- [`IsSymbolLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types). (Conditional version: [`IfSymbolLiteral`](source/if-literal.d.ts))
- [`IsAny`](source/is-any.d.ts) - Returns a boolean for whether the given type is `any`. (Conditional version: [`IfAny`](source/if-any.d.ts))
- [`IsNever`](source/is-never.d.ts) - Returns a boolean for whether the given type is `never`. (Conditional version: [`IfNever`](source/if-never.d.ts))
- [`IsUnknown`](source/is-unknown.d.ts) - Returns a boolean for whether the given type is `unknown`. (Conditional version: [`IfUnknown`](source/if-unknown.d.ts))
Expand Down Expand Up @@ -297,9 +297,9 @@ type ShouldBeNever = IfAny<'not any', 'not never', 'never'>;
- [`NonNegative`](source/numeric.d.ts) - A non-negative `number`/`bigint` (`0 <= x < ∞`).
- [`NegativeInteger`](source/numeric.d.ts) - A negative (`-∞ < x < 0`) `number` that is an integer.
- [`NonNegativeInteger`](source/numeric.d.ts) - A non-negative (`0 <= x < ∞`) `number` that is an integer.
- [`IsNegative`](source/numeric.d.ts) - Returns a boolean for whether the given number is a negative number.
- [`IsFloat`](source/is-float.d.ts) - Returns a boolean for whether the given number is a float, like `1.5` or `-1.5`.
- [`IsInteger`](source/is-integer.d.ts) - Returns a boolean for whether the given number is a integer, like `-5`, `1.0` or `100`.
- [`IsNegative`](source/numeric.d.ts) - Returns a boolean for whether the given number is a negative number. (Conditional version: [`IfNegative`](source/if-negative.d.ts))
- [`IsFloat`](source/is-float.d.ts) - Returns a boolean for whether the given number is a float, like `1.5` or `-1.5`. (Conditional version: [`IfFloat`](source/if-float.d.ts))
- [`IsInteger`](source/is-integer.d.ts) - Returns a boolean for whether the given number is a integer, like `-5`, `1.0` or `100`. (Conditional version: [`IfInteger`](source/if-integer.d.ts))
- [`GreaterThan`](source/greater-than.d.ts) - Returns a boolean for whether a given number is greater than another number.
- [`GreaterThanOrEqual`](source/greater-than-or-equal.d.ts) - Returns a boolean for whether a given number is greater than or equal to another number.
- [`LessThan`](source/less-than.d.ts) - Returns a boolean for whether a given number is less than another number.
Expand Down
27 changes: 27 additions & 0 deletions source/if-equal.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type {IsEqual} from './is-equal';

/**
An if-else-like type that resolves depending on whether the two given types are equal.

@see {@link IsEqual}

@example
```
import type {IfEqual} from 'type-fest';

type ShouldBeTrue = IfEqual<boolean, boolean>;
//=> true

type ShouldBeBar = IfEqual<'not', 'equal', 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfEqual<
A,
B,
TypeIfEqual = true,
TypeIfNotEqual = false,
> = IsEqual<A, B> extends true ? TypeIfEqual : TypeIfNotEqual;
26 changes: 26 additions & 0 deletions source/if-float.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type {IsFloat} from './is-float';

/**
An if-else-like type that resolves depending on whether the given type is a float, like `1.5` or `-1.5`.

@see {@link IsFloat}

@example
```
import type {IfFloat} from 'type-fest';

type ShouldBeTrue = IfFloat<3.14>;
//=> true

type ShouldBeBar = IfFloat<'not float', 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfFloat<
T,
TypeIfFloat = true,
TypeIfNotFloat = false,
> = IsFloat<T> extends true ? TypeIfFloat : TypeIfNotFloat;
26 changes: 26 additions & 0 deletions source/if-integer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type {IsInteger} from './is-integer';

/**
An if-else-like type that resolves depending on whether the given type is an integer, like `-5`, `1.0` or `100`.

@see {@link IsInteger}

@example
```
import type {IfInteger} from 'type-fest';

type ShouldBeTrue = IfInteger<7>;
//=> true

type ShouldBeBar = IfInteger<'not integer', 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfInteger<
T,
TypeIfInteger = true,
TypeIfNotInteger = false,
> = IsInteger<T> extends true ? TypeIfInteger : TypeIfNotInteger;
126 changes: 126 additions & 0 deletions source/if-literal.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import type {IsBooleanLiteral, IsLiteral, IsNumericLiteral, IsStringLiteral, IsSymbolLiteral} from './is-literal';

/**
An if-else-like type that resolves depending on whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).

@see {@link IsStringLiteral}

@example
```
import type {IfStringLiteral} from 'type-fest';

type ShouldBeTrue = IfStringLiteral<'string'>;
//=> true

type ShouldBeBar = IfStringLiteral<false, 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfStringLiteral<
T,
TypeIfStringLiteral = true,
TypeIfNotStringLiteral = false,
> = IsStringLiteral<T> extends true ? TypeIfStringLiteral : TypeIfNotStringLiteral;

/**
An if-else-like type that resolves depending on whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).

@see {@link IsNumericLiteral}

@example
```
import type {IfNumericLiteral} from 'type-fest';

type ShouldBeTrue = IfNumericLiteral<1>;
//=> true

type ShouldBeBar = IfNumericLiteral<'not numeric', 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfNumericLiteral<
T,
TypeIfNumericLiteral = true,
TypeIfNotNumericLiteral = false,
> = IsNumericLiteral<T> extends true ? TypeIfNumericLiteral : TypeIfNotNumericLiteral;

/**
An if-else-like type that resolves depending on whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).

@see {@link IsBooleanLiteral}

@example
```
import type {IfBooleanLiteral} from 'type-fest';

type ShouldBeTrue = IfBooleanLiteral<true>;
//=> true

type ShouldBeBar = IfBooleanLiteral<'not boolean', 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfBooleanLiteral<
T,
TypeIfBooleanLiteral = true,
TypeIfNotBooleanLiteral = false,
> = IsBooleanLiteral<T> extends true ? TypeIfBooleanLiteral : TypeIfNotBooleanLiteral;

/**
An if-else-like type that resolves depending on whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).

@see {@link IsSymbolLiteral}

@example
```
import type {IfSymbolLiteral} from 'type-fest';

type ShouldBeTrue = IfSymbolLiteral<Symbol("key")>;
//=> true

type ShouldBeBar = IfSymbolLiteral<'not symbol', 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfSymbolLiteral<
T,
TypeIfSymbolLiteral = true,
TypeIfNotSymbolLiteral = false,
> = IsSymbolLiteral<T> extends true ? TypeIfSymbolLiteral : TypeIfNotSymbolLiteral;

/**
An if-else-like type that resolves depending on whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).

@see {@link IsLiteral}

@example
```
import type {IfLiteral} from 'type-fest';

type ShouldBeTrue = IfLiteral<"literal">;
//=> true

type ShouldBeBar = IfLiteral<{}, 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfLiteral<
T,
TypeIfLiteral = true,
TypeIfNotLiteral = false,
> = IsLiteral<T> extends true ? TypeIfLiteral : TypeIfNotLiteral;
26 changes: 26 additions & 0 deletions source/if-negative.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type {IsNegative, Numeric} from './numeric';

/**
An if-else-like type that resolves depending on whether the given number is a negative number, like `-80` or `-0.123`.

@see {@link IsNegative}

@example
```
import type {IfNegative} from 'type-fest';

type ShouldBeTrue = IfNegative<-80>;
//=> true

type ShouldBeBar = IfNegative<0.123, 'foo', 'bar'>;
//=> 'bar'
```

@category Type Guard
@category Utilities
*/
export type IfNegative<
T extends Numeric,
TypeIfNegative = true,
TypeIfNotNegative = false,
> = IsNegative<T> extends true ? TypeIfNegative : TypeIfNotNegative;
16 changes: 16 additions & 0 deletions test-d/if-equal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {expectType} from 'tsd';
import type {IfEqual} from '../index';

// `IfEqual` should return `true`/`false` if only `T` is specified
expectType<IfEqual<true, true>>(true);
expectType<IfEqual<string, any>>(false);
expectType<IfEqual<unknown, unknown, 'T', 'F'>>('T');
expectType<IfEqual<1 | undefined, 1, 'T', 'F'>>('F');

// Missing all generic parameters.
// @ts-expect-error
type A = IfEqual;

// Missing `Y` generic parameter.
// @ts-expect-error
type B = IfEqual<number>;
12 changes: 12 additions & 0 deletions test-d/if-float.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {expectType} from 'tsd';
import type {IfFloat} from '../index';

// `IfFloat` should return `true`/`false` if only `T` is specified
expectType<IfFloat<3.41>>(true);
expectType<IfFloat<string>>(false);
expectType<IfFloat<9.000_01, 'T', 'F'>>('T');
expectType<IfFloat<string, 'T', 'F'>>('F');

// Missing generic parameter
// @ts-expect-error
type A = IfFloat;
12 changes: 12 additions & 0 deletions test-d/if-integer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {expectType} from 'tsd';
import type {IfInteger} from '../index';

// `IfInteger` should return `true`/`false` if only `T` is specified
expectType<IfInteger<100>>(true);
expectType<IfInteger<string>>(false);
expectType<IfInteger<-1, 'T', 'F'>>('T');
expectType<IfInteger<string, 'T', 'F'>>('F');

// Missing generic parameter
// @ts-expect-error
type A = IfInteger;
Loading