type IsEqual<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false;
type IndexOf<T extends any[], U extends number | string, A extends any[] = []> = T extends [infer F, ...infer Rest] ? IsEqual<F, U> extends true ? A['length'] : IndexOf<Rest, U, [...A, 0]> : -1
Solution by wendao-liu #35075
// 你的答案
type isAny<T> = 0 extends T ? '1' extends T ? true : false : false
type IndexOf<T, U, Res extends any[] = []> = T extends [infer A, ...infer R] ?
isAny<U> extends true ? isAny<A> extends true ? Res['length'] : IndexOf<R, U, [...Res, A]> :
isAny<A> extends true ? IndexOf<R, U, [...Res, A]> :
[A, U] extends [U, A] ? Res['length'] : IndexOf<R, U, [...Res, A]>
: -1
Solution by heyuelan #34722
// this type take two type parameters (T: tuple, V: any value), and returns tuple which has items until first appearance of V
// eg. TruncateTupleByValue<[1, 2, 3], 3> produces [1, 2]
type TruncateTupleByValue<T extends unknown[], V> = T extends [infer F, ...infer R]
? Equal<F, V> extends true
? []
: [F, ...TruncateTupleByValue<R, V>]
: [];
// index of U corresponds to the length of truncated tuple
// if length of truncated tuple is identical to original one, U does not exist in T, and should return -1
type IndexOf<T extends unknown[], U> = TruncateTupleByValue<T, U> extends [...infer S]
? S extends T
? -1
: S["length"]
: never;
Solution by yukicountry #34342
type IndexOf<T extends any[], U extends number | string, K extends any[] = []> = T extends [infer R, ...infer rest] ? Equal<R, U> extends true ? K['length'] : IndexOf<rest, U, [...K, 1]> : -1
Solution by ouzexi #34092
by Pineapple (@Pineapple0919) #medium #array
Implement the type version of Array.indexOf, indexOf<T, U> takes an Array T, any U and returns the index of the first U in Array T.
type Res = IndexOf<[1, 2, 3], 2>; // expected to be 1
type Res1 = IndexOf<[2,6, 3,8,4,1,7, 3,9], 3>; // expected to be 2
type Res2 = IndexOf<[0, 0, 0], 2>; // expected to be -1
View on GitHub: https://tsch.js.org/5153
...
type IndexOf<T extends unknown[], U extends unknown, N extends number[] = []> = T extends [infer L, ...infer R]
? Equal<U, L> extends true
? N['length']
: IndexOf<R, U, [1, ...N]>
: -1
Solution by veralex #33838
type isEqual<T, U> = T extends U ? U extends T ? true : never : never
type isAny<T> = T extends never ? true : never
type Compare<T, U> = isAny<T> extends never ? isAny<U> extends never ? isEqual<T, U> : false : isAny<U> extends never ? false : true
type IndexOf<T extends any[], U, Arr extends any[] = []> = T['length'] extends Arr['length']
? -1
: true extends Compare<U, T[Arr['length']]>
? Arr['length']
: IndexOf<T, U, [...Arr, 1]>
Solution by PiligrimStas #33777
type IndexOf<
T extends any[],
U extends any,
Temp extends any[] = []
> = T extends [infer First, ...infer Rest extends any[]]
? SimpleEqual<First, U> extends true
? Temp['length']
: IndexOf<Rest, U, [1, ...Temp]>
: -1;
type SimpleEqual<T1, T2> = T1 extends T2
? T2 extends T1
? true
: false
: false;
Solution by sunupupup #33418
export type Equal<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false
type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N
type IndexOf<T extends unknown[], U extends unknown, R extends unknown[] = []> =
T extends [infer F, ...infer Rest] ?
Equal<U, F> extends true ?
IfAny<F,
IfAny<U, R['length'], IndexOf<Rest, U, [...R, true]>>,
IfAny<U,IndexOf<Rest, U, [...R, true]>, R['length']>> :
IndexOf<Rest, U, [...R, true]> :
-1
type cases = [
Expect<Equal<IndexOf<[1, 2, 3], 2>, 1>>,
Expect<Equal<IndexOf<[2, 6, 3, 8, 4, 1, 7, 3, 9], 3>, 2>>,
Expect<Equal<IndexOf<[0, 0, 0], 2>, -1>>,
Expect<Equal<IndexOf<[string, 1, number, 'a'], number>, 2>>,
Expect<Equal<IndexOf<[string, 1, number, 'a', any], any>, 4>>,
Expect<Equal<IndexOf<[string, 'a'], 'a'>, 1>>,
Expect<Equal<IndexOf<[any, 1], 1>, 1>>,
]
Solution by gearonixx #30924
type IndexOf<T extends readonly any[], U, I extends any[] = []> =
T extends [infer F, ...infer R]
? Equal<F,U> extends true
? I['length']
: IndexOf<R, U, [...I, 0]>
: -1
Solution by matallui #30811
type IndexOf<T, U, O extends any[] = []> = T extends [infer A, ...infer B] ? Equal<A, U> extends true ? O['length']: IndexOf<B, U, [...O, A]> : -1
Solution by dreamluo-plus #30662
type IndexOf<T extends unknown[], U extends unknown, C extends unknown[] = []> =
T extends [infer A, ...infer RA]
?
Equal<A, U> extends true
?
C['length']
: IndexOf<RA, U, [...C, A]>
: -1
Solution by zhangqiangzgz #30199
type IndexOf<T extends any[], E, R extends any[] = []> = R['length'] extends T['length'] ? -1 : T[R['length']] extends E ?
R['length'] : IndexOf<T, E, [...R, 0]>;
type indexOf = IndexOf<[1, 2, 3], 2>;
const index: indexOf = 1;
Solution by sundial-dreams #29548
type IsEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B
? 1
: 2
? true
: false;
type IndexOf<T, U, Count extends unknown[] = []> = T extends [
infer F,
...infer R
]
? IsEqual<F, U> extends true
? Count["length"]
: IndexOf<R, U, [...Count, unknown]>
: -1;
Solution by DoubleWoodLin #28779
type IsEqual<X, Y> = X extends Y ? Y extends X ? true : false : false;
type FirstValue<T extends any[]> = T extends [] ? never : T extends [infer R, ...infer _] ? R : never;
type ShiftRest<T extends any[]> = T extends [] ? [] : T extends [infer _, ...infer R] ? R : never;
type Pop<T extends any[]> = T extends [] ? [] : T extends [...infer R, infer _] ? R : never;
type SliceFromStart<T extends any[], U> = IsEqual<FirstValue<T>, U> extends true ? [FirstValue<T>] : [FirstValue<T>, ...(SliceFromStart<ShiftRest<T>, U>)]
type Len<T extends any[], U> = Pop<SliceFromStart<T, U>>["length"];
type IndexOf<T extends any[], U> = Len<T, U> extends T["length"] ? -1 : Len<T, U>;
Solution by breakinferno #28424
type IsEqual<A, B> = (<X>() => X extends A ? 1 : 2) extends <X>() => X extends B
? 1
: 2
? true
: false;
// 思路:构建一个元组类型R,取R的length作为索引,第一次遍历时R为空元组,length为0,以此类推
type IndexOf<T, U, R extends unknown[] = []> = T extends [
infer F,
...infer Rest
]
? IsEqual<F, U> extends true
? R["length"]
: IndexOf<Rest, U, [...R, unknown]>
: -1;
Solution by jiaowoxiaobala #27986
type IndexOf<T extends unknown[], S, V extends unknown[] = []> = T extends []
? -1 : Equal<T[0], S> extends true
? V['length'] : IndexOf<T extends [unknown, ...infer Next]
? Next : [], S, [...V, 1]>
Solution by jiechliu #27802
type IndexOf<T extends any[], I extends number, U extends any[] = []> = T extends [infer N, ...infer Rest] ? N extends I ? U['length'] : IndexOf<Rest, I, [...U, N]> : -1
Solution by HenrryShaw #27761
The solution is too long to fit in an issue, so here's a gist. https://gist.github.com/RuyiLi/344242fc304fb70a562c97a39e67dbee
Solution by RuyiLi #27746
type IndexOf<T extends unknown[], N, C extends unknown[] = []> = T extends [
infer R,
...infer V
]
? R extends N
? C["length"]
: IndexOf<V, N, [unknown, ...C]>
: -1;
Solution by ryuji-1to #27368
type IndexOf<T, U, P extends unknown[] = []> =
T extends [infer F, ...infer R] ? Equal<F, U> extends true ? P['length'] : IndexOf<R, U, [...P, 1]> : -1
Solution by smileboyi #27108
type IndexOf<T extends unknown[], U, i extends unknown[] = []> = Equal<T[i['length']],U> extends true ? i['length'] : i['length'] extends T['length'] ? -1 : IndexOf<T,U,[...i,T[i['length']]]>
Solution by WangZiChu199910252255 #26897
/**
* @description judge whether U is equal to T
*/
type isEqual<U, T> = U extends T ? (T extends U ? true : false) : false;
/**
* @description 获取元组中指定元素的索引
* @param T 元组
* @param U 指定元素
* @param Length 相当于一个计数器,每次递归都会将当前元素推入其中,最后返回Length的长度
*/
type IndexOf<T, U, Length extends unknown[] = []> = T extends [infer First, ...infer Rest]
? isEqual<First, U> extends true
? Length['length']
: IndexOf<Rest, U, [...Length, First]>
: -1;
Solution by Lu9709 #26865
type Equals<A, B> = A extends B ? (B extends A ? true : false) : false;
type IndexOf<T extends unknown[], U extends unknown, COUNT extends 0[] = []> = T extends [infer Head, ...infer Tail] ? Equals<U,Head> extends true ? COUNT['length'] : IndexOf<Tail,U, [...COUNT,0]> : -1
Solution by ScarboroughCoral #26506
type IndexOf<T extends unknown[], U, Res extends unknown[] = []> =
T extends [infer F, ...infer R]
? Equal<F, U> extends true
? Res['length']
: IndexOf<R, U, [...Res, 0]>
: -1```
Solution by liuk123456789 #26127
// your answers
type MyEqual<X, Y> =
X extends Y
? Y extends X
? true
: false
: false
type IndexOf<T extends unknown[], U extends unknown, Arr extends unknown[] = []> =
T extends [infer X, ...infer Y]
? MyEqual<X, U> extends true
? Arr['length']
: IndexOf<Y, U, [unknown, ...Arr]>
: -1
Solution by kiki-zjq #25669
type IndexOf<
T extends unknown[],
U,
Acc extends unknown[] = []
> = T extends [infer First, ...infer Rest]
? Equal<First, U> extends true
? Acc['length']
: IndexOf<Rest, U, [...Acc, 1]>
: -1
Solution by NeylonR #24273
// your answers
type MyEqual<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
? 1
: 2
? true
: false
type IndexOf<
T extends any[],
U,
Index extends any[] = []
> = T['length'] extends Index['length']
? -1
: MyEqual<T[Index['length']], U> extends true
? Index['length']
: IndexOf<T, U, [...Index, any]>
Solution by studymachiney #24113
type IndexOf<T extends any[], U, _Counter extends 1[] = []> = T extends [infer F, ...infer R] ?
Equal<F, U> extends true ? _Counter[`length`]/*return*/ : IndexOf<R, U, [..._Counter, 1]> :
-1/*return*/;
// old way
// type SimpleEqual<T, U> = T extends U ? U extends T ? true : false : false;
// type IndexOf<T extends any[], U, _Counter extends any[] = []> =
// T extends [] ? -1 :
// (
// SimpleEqual<U, T[0]> extends true ?
// _Counter["length"] :
// (
// T extends [any, ...infer R] ? IndexOf<R, U, [..._Counter, unknown]> : T
// )
// );
Solution by E-uler #23985
type isEqual<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false
type IndexOf<T extends unknown[], U, S extends unknown[] = []> = T extends [infer L, ...infer Rest] ? isEqual<L, U> extends true ? S['length'] : IndexOf<Rest, U, [...S, L]> : -1;
Solution by asurewall #23133
type IndexOf<T extends unknown[], U, Acc extends unknown[] = []> = T extends [infer F, ...infer R] ?
Equal<U, F> extends true ? [...Acc]['length'] : IndexOf<R, U, [...Acc, F]> : -1
Solution by snakeUni #23118