跳到主要内容

Includes

介绍

在类型系统里实现 JavaScript 的 Array.includes 方法,这个类型接受两个参数,返回的类型要么是 true 要么是 false

例如

ts
type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'>; // expected to be `false`
ts
type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'>; // expected to be `false`
View on GitHub

起点

ts
/* _____________ Your Code Here _____________ */
type Includes<T extends readonly any[], U> = any;
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Kars'>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 7>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 4>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3], 2>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3], 1>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[{}], { a: 'A' }>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[boolean, 2, 3, 5, 6, 7], false>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[true, 2, 3, 5, 6, 7], boolean>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[false, 2, 3, 5, 6, 7], false>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[{ a: 'A' }], { readonly a: 'A' }>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[{ readonly a: 'A' }], { a: 'A' }>, false>>
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
];
ts
/* _____________ Your Code Here _____________ */
type Includes<T extends readonly any[], U> = any;
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Kars'>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 7>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 4>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3], 2>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[1, 2, 3], 1>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[{}], { a: 'A' }>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[boolean, 2, 3, 5, 6, 7], false>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[true, 2, 3, 5, 6, 7], boolean>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[false, 2, 3, 5, 6, 7], false>, true>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[{ a: 'A' }], { readonly a: 'A' }>, false>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Includes<[{ readonly a: 'A' }], { a: 'A' }>, false>>
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
];
take the challenge

解决方案

Spoiler warning // Click to reveal answer
ts
type Includes<T extends any[], U> = {
[P in T[number]]: true
}[U] extends true ? true : false
 
 
// 存在问题
/**
* 1.只满足propertyKey类型判断
* 2.对象类型判断失效 [{}][]
* 3.联合类型判断失效 Includes<[boolean], false> Includes<[null|undefined], null>
*/
 
ts
type Includes<T extends any[], U> = {
[P in T[number]]: true
}[U] extends true ? true : false
 
 
// 存在问题
/**
* 1.只满足propertyKey类型判断
* 2.对象类型判断失效 [{}][]
* 3.联合类型判断失效 Includes<[boolean], false> Includes<[null|undefined], null>
*/
 
ts
// 方案2
 
type IsEqual<T,U> =
(<G>() => G extends T ? 1 : 2) extends
(<G>() => G extends U ? 1 : 2)
? true
: false;
 
type Includes<T extends any[], U> =
IsEqual<T[0], U> extends true
? true
: T extends [T[0], ...infer rest]
? Includes<rest, U>
: false;
 
// 存在的问题 Includes<[], undefined>返回true
ts
// 方案2
 
type IsEqual<T,U> =
(<G>() => G extends T ? 1 : 2) extends
(<G>() => G extends U ? 1 : 2)
? true
: false;
 
type Includes<T extends any[], U> =
IsEqual<T[0], U> extends true
? true
: T extends [T[0], ...infer rest]
? Includes<rest, U>
: false;
 
// 存在的问题 Includes<[], undefined>返回true
ts
// 方案3
 
type Includes<T,U> = T extends [infer F, ...infer Rest]
? F extends U ? true : Includes<Rest, U>
: false;
 
ts
// 方案3
 
type Includes<T,U> = T extends [infer F, ...infer Rest]
? F extends U ? true : Includes<Rest, U>
: false;
 
view more solutions