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 Includes type #217

Merged
merged 11 commits into from
Aug 5, 2021
Merged

Add Includes type #217

merged 11 commits into from
Aug 5, 2021

Conversation

Yash-Singh1
Copy link
Contributor

@Yash-Singh1 Yash-Singh1 commented Jun 2, 2021

Resolves #216

The problem is that my solution to Includes works only with the PropertyKey type for Item, because it makes the values the key and the value a boolean, then checks if the value is true for the property with the key of Item. The other solution is:

type Includes<T extends readonly any[], U> = U extends T[number] ? true : false;

However as shown in type-challenges/type-challenges#1432, this solution does not work, because it uses extends allowing [{a: 5}] to include {}. Any ideas on supporting Item for types other than PropertyKey and at the same time not running into the extends problem (https://github.com/Yash-Singh1/type-fest/blob/main/test-d/includes.ts#L22)?

test-d/includes.ts Outdated Show resolved Hide resolved
test-d/includes.ts Outdated Show resolved Hide resolved
ts41/includes.d.ts Outdated Show resolved Hide resolved
@sindresorhus
Copy link
Owner

How can we get this moving forward?

@Yash-Singh1
Copy link
Contributor Author

I did find a solution but it depends on the Equal type presented here: microsoft/TypeScript#27024 (comment). Should I change this PR to add Includes and Equal or should I simply update the Includes type to use it inline? Here it is by the way:

export type Includes<Value extends any[], Item> =
  (<G>() => G extends Value[0] ? 1 : 2) extends
  (<G>() => G extends Item ? 1 : 2)
	? true
	: Value extends [Value[0], ...infer rest]
		? Includes<rest, Item>
		: false;

@sindresorhus
Copy link
Owner

sindresorhus commented Aug 2, 2021

Great. Make it a separate internal type called IsEqual, but put it inside the same file as Includes. And link to microsoft/TypeScript#27024 (comment) in a code comment for context.

@Yash-Singh1 Yash-Singh1 marked this pull request as ready for review August 2, 2021 17:52
const objectIncludesPass: Includes<[{ a: 1 }], { a: 1 }> = true;
expectType<true>(objectIncludesPass);

// @ts-expect-error
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use the expectError assertion method instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use the expectError assertion method instead.

When you say instead, do you mean without the // @ts-expect-error, because I couldn't figure out how to use the expectError assertion method works without it. Is this how I am supposed to do it?:

// @ts-expect-error
const oneArgIncludes: Includes<['my', 'array', 'has', 'stuff']> = false;
expectError<Includes<['my', 'array', 'has', 'stuff']>>(oneArgIncludes);

Removing the // @ts-expect-error, gives an error (as expected):

✖  34:22  Generic type Includes requires 2 type argument(s).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say instead, do you mean without the // @ts-expect-error

Yes

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to put the type inside the method call to expectError. tsd only ignores TS error inside the ().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test-d/includes.ts Outdated Show resolved Hide resolved
@sindresorhus sindresorhus merged commit bf4fc28 into sindresorhus:main Aug 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: Includes type
2 participants