Skip to content

Commit

Permalink
Add Includes type (#217)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
Yash-Singh1 and sindresorhus authored Aug 5, 2021
1 parent 55426a0 commit bf4fc28
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 9 deletions.
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ Click the type names for complete docs.
- [`Entries`](source/entries.d.ts) - Create a type that represents the type of the entries of a collection.
- [`SetReturnType`](source/set-return-type.d.ts) - Create a function type with a return type of your choice and the same parameters as the given function type.
- [`Asyncify`](source/asyncify.d.ts) - Create an async version of the given function type.
- [`Includes`](ts41/includes.ts) - Returns a boolean for whether the given array includes the given item.
- [`Simplify`](source/simplify.d.ts) - Flatten the type output to improve type hints shown in editors.

### Template literal types
Expand Down
39 changes: 39 additions & 0 deletions test-d/includes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {expectError, expectType} from 'tsd';
import {Includes} from '..';

const includesEmptyArray: Includes<[], 'abc'> = false;
expectType<false>(includesEmptyArray);

const includesSingleItemArray: Includes<['colors'], 'colors'> = true;
expectType<true>(includesSingleItemArray);

const includesComplexMultiTypeArray: Includes<[
{
prop: 'value';
num: 5;
anotherArr: [1, '5', false];
},
true,
null,
'abcd'
], 'abc'> = false;
expectType<false>(includesComplexMultiTypeArray);

const noExtendsProblem: Includes<[boolean], true> = false;
expectType<false>(noExtendsProblem);

const objectIncludes: Includes<[{}], {a: 1}> = false;
expectType<false>(objectIncludes);

const objectIncludesPass: Includes<[{a: 1}], {a: 1}> = true;
expectType<true>(objectIncludesPass);

declare const anything: any;

expectError<Includes>(anything);

expectError<Includes<['my', 'array', 'has', 'stuff']>>(anything);

expectError<Includes<'why a string?', 5>>(anything);

expectError<Includes<{key: 'value'}, 7>>(anything);
31 changes: 31 additions & 0 deletions ts41/includes.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
Returns a boolean for whether given two types are equal.
@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
*/
type IsEqual<T, U> =
(<G>() => G extends T ? 1 : 2) extends
(<G>() => G extends U ? 1 : 2)
? true
: false;

/**
Returns a boolean for whether the given array includes the given item.
This can be useful if another type wants to make a decision based on whether the array includes that item.
@example
```
import {Includes} from 'type-fest';
type hasRed<array extends any[]> = Includes<array, 'red'>;
```
@category Utilities
*/
export type Includes<Value extends any[], Item> =
IsEqual<Value[0], Item> extends true
? true
: Value extends [Value[0], ...infer rest]
? Includes<rest, Item>
: false;
1 change: 1 addition & 0 deletions ts41/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ export {DelimiterCasedProperties} from './delimiter-cased-properties';
export {DelimiterCasedPropertiesDeep} from './delimiter-cased-properties-deep';
export {Split} from './split';
export {Trim} from './trim';
export {Includes} from './includes';
export {Get} from './get';
export {LastArrayElement} from './last-array-element';
10 changes: 1 addition & 9 deletions ts41/screaming-snake-case.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import {SplitIncludingDelimiters} from './delimiter-case';
import {SnakeCase} from './snake-case';

/**
Returns a boolean for whether the given array includes the given item.
*/
type Includes<Value extends any[], Item> = {
[P in keyof Value & number as Value[P]]: true;
}[Item] extends true
? true
: false;
import {Includes} from './includes';

/**
Returns a boolean for whether the string is screaming snake case.
Expand Down

0 comments on commit bf4fc28

Please sign in to comment.