type MyEqual<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false
type Includes<T extends readonly any[], U> = T extends [] ? false :
MyEqual<T[0], U> extends true
? true
: T extends [infer f, ...infer rest]
? Includes<rest, U>
: false;
Solution by watanaki #35195
type IsEquar<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
type Includes<T extends readonly any[], U> = T extends [infer F, ...infer Rest]
? IsEquar<F, U> extends true
? true
: Includes<Rest, U>
: false;
Solution by wendao-liu #35085
My answer is inspired by util implementation of Equal but more understandable i think. It passes all given tests
type MyEquals<T,U> =
Readonly<T> extends T ? Readonly<U> extends T ? true : false : false;
type Includes<T extends readonly any[], U> =
T extends readonly [infer HEAD, ...infer TAIL] ?
Equal<HEAD,U> extends true ? true : Includes<TAIL, U> :
false;
Solution by CrimsoonXIII #35047
type Includes<T extends readonly unknown[], P> = P extends T[number] ? true : false
Solution by ClarityOfMind #34994
type Includes<T extends readonly any[], U> = T extends [infer First, ...infer Rest] ? (First extends U ? (U extends First ? true : false) : Includes<Rest, U>) : false;
Solution by raeyoung-kim #34957
type TupleToUnion<T extends readonly any[]> = T extends [infer First, ...infer Rest] ? First | TupleToUnion<Rest> : never;
type Includes<T extends any[], K> = K extends TupleToUnion<T> ? true : false;
We could make a TupleToUnion.
Solution by DearICE #34907
type Includes<T extends readonly any[], U> =
Equal<U, T[0]> extends true
? true
: (T extends [any, ...infer R]
? (R extends [] // if R is an empty array, the search should be terminated
? false
: Includes<R, U>)
: false)
Solution by floatDreamWithSong #34871
type Includes<T extends readonly any[], K> = K extends T[number] ? true : false
Solution by weitongtong #34847
type TupleIndexes<T extends readonly any[]> = { [K in keyof T]: K }[number]
่ทๅๅ
็ปT็ๆๆ็ดขๅผ
type AllEqual<T extends readonly any[], U, P extends number> = P extends P ? Equal<T[P], U> : never
ๅฉ็จDistributive Conditional Type๏ผๅฆๆTไธญๆๆๅ
็ด ้ฝๅUไธ็ธ็ญๅไธบfalseใ่ฅTๆฐๆไธไธชๅ
็ด ๅU็ธ็ญๅไธบtrue๏ผ่ฅTๅซๆๅ
็ด ๅU็ธ็ญๅไธบbooleanใ
type Includes<T extends readonly any[], U> = AllEqual<T, U, TupleIndexes<T>> extends false ? false : true
Solution by 2083335157 #34838
// @reference https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
type IsEqual<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2)
? true
: false;
type Includes<T extends readonly any[], U> = T extends [infer First, ...infer Rest]
? IsEqual<First, U> extends true
? true
: Includes<Rest, U>
: false;
Solution by eunsukimme #34815
// ไฝ ็็ญๆก
type Includes<T extends readonly any[], U> = {
[key in keyof T]: Equal<T[key], U> extends true ? true: never;
}[number] extends never ? false : true
// ๅๅฉ never ็ฉบ้
Solution by Atlas-lili #34729
// your answers
type Includes<T extends readonly any[], U> = T extends [infer P, ...infer R]
? Equal<P, U> extends true
? true
: Includes<R, U>
: false;
Solution by zeyuanHong0 #34719
type Includes<T extends readonly any[], U> = T extends [infer I, ...infer E] ? Equal<I, U> extends true ? true : Includes<E, U> : false
Solution by nathan2slime #34662
type Includes<T extends readonly unknown[], U> =
T extends [infer First, ...infer Rest]
? Equal<First, U> extends true ? true : Includes<Rest, U>
: false;
Solution by devshinthant #34548
type Includes<T extends readonly any[], U> =
T extends [infer Head, ... infer Tail] ?
Equal<Head, U> extends true ? true : Includes<Tail, U>
: false
Solution by binhdv155127 #34470
// ์ฌ๊ธฐ ํ์ด๋ฅผ ์
๋ ฅํ์ธ์
type Equal<X, Y> =
(<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
type Includes<T extends readonly any[], U> = T extends [infer F, ...infer Rest]
? Equal<F, U> extends true
? true
: Includes<Rest, U>
: false;
Solution by LeeKangHyun #34463
type Equal<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false;
type Includes<T extends readonly any[], U> = T extends [infer F, ...infer R] ? Equal<F, U> extends true ? true : Includes<R, U> : false
Solution by ktim816 #34427
type Includes<T extends readonly any[], U> =
T extends [infer F, ...infer R]
? Equal<F, U> extends true
? true
: Includes<R, U>
: false;
Solution by bkdragon0228 #34377
type Includes<T extends readonly any[], U> = T extends [infer Fisrt, ...infer Reset]
? Equal<Fisrt, U> extends true ? true : Includes<Reset, U>
: false
Solution by rookie-luochao #34363
export type IsEqual<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false
type Includes<T extends readonly any[], U> = T extends [infer A,...infer Reset] ? IsEqual <U,A> extends true ?true:Includes<Reset,U> : false
Solution by FrankWangMing #34340
type Eq<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false
type Includes<T extends readonly any[], U> =
T extends [infer Head, ...infer Tail]
? Eq<U, Head> extends true
? true
: Includes<Tail, U>
: false
Solution by souzaramon #34335
JavaScript์ Array.includes
ํจ์๋ฅผ ํ์
์์คํ
์์ ๊ตฌํํ์ธ์. ํ์
์ ๋ ์ธ์๋ฅผ ๋ฐ๊ณ , true
๋๋ false
๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค.
์์:
type isPillarMen = Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Dio">; // expected to be `false`
๋ณด์๋ง์ ์๋ํ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
type Includes<T extends readonly any[], U> = U extends T[number] ? true : false;
ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.
Includes<[{}], { a: "A" }>; // true...?
ํด๋น ํ์ ์ด true ๊ฐ ๋์ค๋๊ฒ์ด ์ด์ํ์ต๋๋ค. ๊ทธ ์ด์ ๋ {} ํ์ ์ "๋น ๊ฐ์ฒด ํ์ "์ผ๋ก, ๋ชจ๋ ๊ฐ์ฒด ํ์ ์ ์์ ํ์ (supertype)์ผ๋ก ๊ฐ์ฃผ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
TypeScript์์ {} ํ์ ์ **"๋น ๊ฐ์ฒด ํ์ "**์ผ๋ก ์๋ ค์ ธ ์์ต๋๋ค. ์ด๋ ๊ฐ์ฒด๋ฅผ ์๋ฏธํ์ง๋ง, ๊ทธ ๊ฐ์ฒด์ ์ด๋ค ํน์ ํ ์์ฑ์ด ์์์ ๋ช ์ํ์ง ์์ ํ์ ์ ๋๋ค.
{} ํ์ ์ ์ฌ์ค์ ๋ชจ๋ JavaScript ๊ฐ๊ณผ ํธํ๋ฉ๋๋ค. ์ด๋ ์ซ์, ๋ฌธ์์ด, ๋ฐฐ์ด, ํจ์, ๊ฐ์ฒด, null, undefined๋ฅผ ํฌํจํ ๋ชจ๋ ๊ฐ์ด {} ํ์ ์ ํ ๋น๋ ์ ์์์ ์๋ฏธํฉ๋๋ค.
let emptyObject: {} = {}; // ๋น ๊ฐ์ฒด ํ ๋น ๊ฐ๋ฅ
let numberValue: {} = 123; // ์ซ์ ํ ๋น ๊ฐ๋ฅ
let stringValue: {} = "Hello"; // ๋ฌธ์์ด ํ ๋น ๊ฐ๋ฅ
let arrayValue: {} = [1, 2, 3]; // ๋ฐฐ์ด ํ ๋น ๊ฐ๋ฅ
let functionValue: {} = () => {}; // ํจ์ ํ ๋น ๊ฐ๋ฅ
// ๋ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด ํ์
์๋ ํ ๋น ๊ฐ๋ฅ
let specificObject: {} = { a: "hello", b: 42 };
object ํ์ ์ ์์ ๊ฐ(primitive types)์ ํ์ฉํ์ง ์์ง๋ง, {} ํ์ ์ ์์ ๊ฐ๋ ํ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, number๋ string๋ {} ํ์ ์ ํ ๋น๋ ์ ์์ง๋ง, object ํ์ ์๋ ํ ๋น๋ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ {} ๋ด๋ถ์์๋ ํ์ธํ์ฌ ์๋ฒฝํ ํธํํ๋์ง ํ์ธํ ํ์๊ฐ ์์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ ๊ท์ ์ธ ๋ฐฉ์์ผ๋ก ์ด๋ฐ๊ฑด ์ด๋จ๊น์? ์ ํฌ๊ฐ DeepReadonly ๋ฅผ ๋ง๋ค์ด์ ์ ๊ท์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๊ฒ์ฒ๋ผ (์ ์ readonly์ ํ์ด๊ฐ ์ ํ ์์ต๋๋ค.) ์ด๋ฒ์๋ ์ ๊ท์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๊ฒ ์ต๋๋ค.
type Includes<Value extends any[], Item> = Value extends [
infer First,
...infer Rest
]
? Equal<First, Item> extends true // Equal์ ์ฌ์ฉํด๋ณด์์ต๋๋ค! ๋น์ฐํ ์ฌ์ฉํ๋ฉด ์๋๊ฒ ์ง๋ง ๋ง์ด์ฃ .
? true
: Includes<Rest, Item>
: false;
/* _____________ ํ
์คํธ ์ผ์ด์ค _____________ */
import type { Equal, Expect } from "@type-challenges/utils";
type cases = [
Expect<
Equal<Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Kars">, true>
>,
Expect<
Equal<Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Dio">, false>
>,
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 7>, true>>,
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 4>, false>>,
Expect<Equal<Includes<[1, 2, 3], 2>, true>>,
Expect<Equal<Includes<[1, 2, 3], 1>, true>>,
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>>,
Expect<Equal<Includes<[false, 2, 3, 5, 6, 7], false>, true>>,
Expect<Equal<Includes<[{ a: "A" }], { readonly a: "A" }>, false>>,
Expect<Equal<Includes<[{ readonly a: "A" }], { a: "A" }>, false>>,
Expect<Equal<Includes<[1], 1 | 2>, false>>,
Expect<Equal<Includes<[1 | 2], 1>, false>>,
Expect<Equal<Includes<[null], undefined>, false>>,
Expect<Equal<Includes<[undefined], null>, false>>
];
๋ฌธ์ ์์ด ๋ชจ๋ ์ ๋ฐํํ๋๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด์ Equal์ ๋์ ํ ์ ์๋ ํจ์๋ฅผ ๋ง๋ค๋ฉด ๋๊ฒ ๊ตฐ์. ์ํ๊น๊ฒ๋ Equal์ ๋์ ํ๋ ์ ๋ค๋ฆญ์ ์์ผ๋ ์ง์ ๊ตฌํ์ ํตํด ๋ง๋ค์ด ์ฃผ์ด์ผ ํฉ๋๋ค.
/**
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;
๋ค์๊ณผ ๊ฐ์ด ts issues์ ํฌํจ๋์ด ์๋ IsEqual์ ์ฌ์ฉํด๋ณด์์ต๋๋ค.
/* _____________ ์ฌ๊ธฐ์ ์ฝ๋ ์
๋ ฅ _____________ */
type IsEqual<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U
? 1
: 2
? true
: false;
type Includes<Value extends any[], Item> = Value extends [
infer First,
...infer Rest
]
? IsEqual<First, Item> extends true
? true
: Includes<Rest, Item>
: false;
/* _____________ ํ
์คํธ ์ผ์ด์ค _____________ */
import type { Equal, Expect } from "@type-challenges/utils";
type cases = [
Expect<
Equal<Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Kars">, true>
>,
Expect<
Equal<Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Dio">, false>
>,
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 7>, true>>,
Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 4>, false>>,
Expect<Equal<Includes<[1, 2, 3], 2>, true>>,
Expect<Equal<Includes<[1, 2, 3], 1>, true>>,
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>>,
Expect<Equal<Includes<[false, 2, 3, 5, 6, 7], false>, true>>,
Expect<Equal<Includes<[{ a: "A" }], { readonly a: "A" }>, false>>,
Expect<Equal<Includes<[{ readonly a: "A" }], { a: "A" }>, false>>,
Expect<Equal<Includes<[1], 1 | 2>, false>>,
Expect<Equal<Includes<[1 | 2], 1>, false>>,
Expect<Equal<Includes<[null], undefined>, false>>,
Expect<Equal<Includes<[undefined], null>, false>>
];
Solution by adultlee #34121
type Includes<T extends readonly any[], U> = T extends [infer P, ...infer rest] ? Equal<P, U> extends true ? true : Includes<rest, U> : false
Solution by ouzexi #33971
type Includes<T extends readonly any[], U> = T extends [infer First, ...infer Rest]
? Equal<U, First> extends true
? true
: Includes<Rest, U>
: false
Solution by notsecret32 #33863
type Includes<T extends readonly any[], U> = T extends [infer L, ...infer R]
? Equal<L, U> extends true
? true
: Includes<R, U>
: false
Solution by veralex #33756
type Equal<A, B> = (<T>() => T extends A ? 1 : 0) extends (<T>() => T extends B ? 1 : 0) ? true : false
type Includes<T extends readonly any[], U> = T extends [infer A, ...infer Rest]
? Equal<A, U> extends true
? true
: Includes<Rest, U>
: false
Solution by laplace1009 #33707
type Includes<T extends readonly any[], U> =
T extends [infer Head , ...infer Tail]
? Equal<Head, U> extends true
? true
: Includes<Tail, U>
: false;
้ฃใใใใ...
Head, Tailใใใใงๅบใฆใใใจใฏๆใใชใใฃใใ
Equal
ไฝฟใใฎใฏๆณๅใงใใชใใฃใ
Solution by okabe-yuya #33687
// ไฝ ็็ญๆก
type Includes<T extends unknown[], K> = K extends keyof T[number] ? true : false;
Solution by SZGG2333 #33602
type Includes<P extends readonly any[], U> = true extends {
[K in keyof P]: (<T>() => T extends U ? 1 : 2) extends <T>() => T extends P[K] ? 1 : 2
? true
: false;
}[number]
? true : false;
Solution by Alex-Nicalace #33406
// ์ฌ๊ธฐ ํ์ด๋ฅผ ์
๋ ฅํ์ธ์
type Includes<T extends readonly any[], U> = T extends [infer F, ...infer Rest]
? Equal<F, U> extends true
? true
: Includes<Rest, U>
: false;
Solution by awesomelon #33368