Open utterances-bot opened 3 years ago
Sorry but the last three tests fail with this solution. I mean:
Expect<Equal<Includes<[{}], { a: 'A' }>, false>>,
Expect<Equal<Includes<[boolean, 2, 3, 5, 6, 7], false>, false>>,
Expect<Equal<Includes<[true, 2, 3, 5, 6, 7], boolean>, false>>
The extends
clause is not enough.
@jfet97 they've must be added those tests recently. Do you have any ideas on how we can improve the solution?
@ghaiklor In my solution, that is quite different, I've used the Alike
util type:
import { Alike } from '@type-challenges/utils';
type Includes<T extends readonly any[], U> =
T extends [] ?
false :
T extends [infer HEAD, ...infer REST] ?
true extends Alike<HEAD, U> ?
true :
Includes<REST, U> :
never
@jfet97 it's hard to tell that this solution is for "easy" level ๐ฑ IMHO, by introducing those tests they've raised the level of the challenge.
@ghaiklor I agree with you, maybe it is now a medium difficult one.
my solution , check each value recursively
type Includes<T extends readonly any[], U> =
T extends [infer First, ...infer Rest]
? Equal<First, U> extends true
? true
: Includes<Rest, U>
: false
I'm wondering if there is a way to 'infer' the indexed type. Which would allow something along the lines of:
type Includes<T extends unknown[], U> = U extends T[number](infer S) ?
S extends U ? true : false
: false
which is exactly what the above commenter suggested! Should remember to still use my :eyes: when i'm exercising my :brain:
type Includes<T extends readonly any[], U> = {} extends {
[K in keyof T as Equal<T[K], U> extends true ? K : never]: T[K];
} ? false : true
type Includes<T extends readonly any[], U> = {} extends { [K in keyof T as Equal<T[K], U> extends true ? K : never]: T[K]; } ? false : true
This solution causes following test case failed accidentally, because the length of testing tuple literal happens to be 1.
Expect<Equal<Includes<[1 | 2], 1>, false>>
A trivial Omit
of length field should work fine:
type Includes<T extends readonly any[], U> = {} extends {
[I in keyof Omit<T, "length"> as Equal<T[I], U> extends true ? I : never ]: T[I]
} ? false : true
@ghaiklor When you mention distributive conditional types:
E.g. if you write 2 extends 1 | 2, what TypeScript will do is actually replace it with two conditionals 2 extends 1 and 2 extends 2.
Don't the distributive types apply when left hand side of extends
is union? e.g.X extends 1 ? true:false
, X
should be union for distribution to take place (also it must be naked generic type). In your example union is on the right hand side.
@gmoniava you are right, it is a typo, thanks for noticing! I'll fix it right now.
a4da117bfb4a997a593132df53bed621a4ae3060
@ghaiklor yes but I think there is another problem. The left hand side of extends
in the final solution, which is U
, is never a union in test cases, and even if it were union then I think your solution would not work because it could return boolean
instead of true
or false
. So I think we should not mention distributive conditionals in the solution.
@gmoniava you made me to think a minute here ๐
Yeah, I remember now that we don't use distribution here at all, but instead checking if the element is in union, not vice versa. I have deleted the paragraph about distributivity here -> 6c07f782234e5e819412d2fe4bc3765a9fb6610e.
Includes
This project is aimed at helping you better understand how the type system works, writing your own utilities, or just having fun with the challenges.
https://ghaiklor.github.io/type-challenges-solutions/en/easy-includes.html