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

「重学TS 2.0 」TS 练习题第四十二题 #63

Open
semlinker opened this issue Sep 30, 2021 · 12 comments
Open

「重学TS 2.0 」TS 练习题第四十二题 #63

semlinker opened this issue Sep 30, 2021 · 12 comments

Comments

@semlinker
Copy link
Owner

实现 IndexOf 工具类型,用于获取数组类型中指定项的索引值。若不存在的话,则返回 -1 字面量类型。具体的使用示例如下所示:

type IndexOf<A extends any[], Item> = // 你的实现代码

type Arr = [1, 2, 3, 4, 5]
type I0 = IndexOf<Arr, 0> // -1
type I1 = IndexOf<Arr, 1> // 0
type I2 = IndexOf<Arr, 3> // 2

请在下面评论你的答案

@sunboyZgz
Copy link

type IndexOf<
A extends any[],
Item,
Index extends any[] = []

= Length extends 0
? -1
: Head extends Item
? Length
: IndexOf<Tail, Item, Push<Index, "">>;

type Arr = [1, 2, 3, 4, 5];
type I0 = IndexOf<Arr, 0>; // -1
type I1 = IndexOf<Arr, 1>; // 0
type I2 = IndexOf<Arr, 3>; // 2

@zhaoxiongfei
Copy link

// 实现 IndexOf 工具类型,用于获取数组类型中指定项的索引值。若不存在的话,则返回 -1 字面量类型。具体的使用示例如下所示:

type IndexOf<A extends any[], Item, F extends any[] = []> = A extends [infer H, ...infer T]
  ? H extends Item
    ? F["length"]
    : IndexOf<T, Item, [...F, H]>
  : -1;

type Arr = [1, 2, 3, 4, 5];
type I0 = IndexOf<Arr, 0>; // -1
type I1 = IndexOf<Arr, 1>; // 0
type I2 = IndexOf<Arr, 3>; // 2

@zhaoxiongfei
Copy link

type IsEqual<T, U> = [T] extends [U] ? [U] extends [T] ? true : false : false;
type IndexOf<A extends any[], Item, F extends any[] = []> = A extends [infer H, ...infer T]
  ? IsEqual<H, Item> extends true
    ? F["length"]
    : IndexOf<T, Item, [...F, H]>
  : -1;

type Arr = [1, 2, 3, 4, 5];
type I0 = IndexOf<Arr, 0>; // -1
type I1 = IndexOf<Arr, 1>; // 0
type I2 = IndexOf<Arr, 3>; // 2
type I3 = IndexOf<[1, 3 | 7], 3>; // -1
type I4 = IndexOf<[never, 3 | 7], 3>; // -

注意事项: 构造数组来记录当前迭代到了哪一项,这样匹配到之后就能返回长度,就是索引值。
另外比配每一项的时候用之前的 IsEqual的方式,这样能避免元素里有联合类型导致的错误。

@douhao1988
Copy link

type IndexOf<A extends any[], Item, C extends any[] = []> =
    A extends [infer F, ...infer L]
        ? F extends Item ?
            C['length']
                : IndexOf<L, Item, [...C, '']>
                    : -1

type Arr = [1, 2, 3, 4, 5]
type I01 = IndexOf<Arr, 0> // -1
type I11 = IndexOf<Arr, 1> // 0
type I21 = IndexOf<Arr, 3> // 2

@mingzhans
Copy link

type IsEqual<T, U> = [T] extends [U] ? [U] extends [T] ? true : false : false;
// 将字符串转换为数字
//一种方法
// type IsRepeat<A extends any, S extends string, T extends any[] = []> =  `${T['length']}` extends S ? T['length'] : IsRepeat<A,S, [...T,A]>
// type EE<A extends any[], Item> = {
//     [p in keyof A as IsEqual<A[p],Item> extends true ? p : never]: p
// }
// type IndexOf<A extends any[], Item> = EE<A, Item>[keyof  EE<A, Item>] extends never ? -1 : IsRepeat<'',EE<A, Item>[keyof  EE<A, Item>]>// 你的实现代码
// 二种方法
type  IndexOf<A extends any[], Item, S extends any[] = []> = A extends [infer R, ...infer Rest] ? IsEqual<R,Item> extends true ? S['length'] : IndexOf<Rest, Item, [...S, R]> : -1
type Arr = [1, 2, 3, 4, 5, '66']
type I0 = IndexOf<Arr, 0> // -1
type I1 = IndexOf<Arr, 1> // 0
type I2 = IndexOf<Arr, 3> // 2
type I3 = IndexOf<Arr, '66'> // 5

都要用到数组的length属性,即查找类型

@Gengar-666
Copy link

type Push<A extends any[], U> = A extends [infer P] ? [P, U] : [U]

type IndexOf<A extends any[], Item extends number, T extends any[] = []> = A extends [infer P1, ...infer P2] 
  ? P1 extends Item 
    ? T['length']
    : IndexOf<P2, Item, Push<T, 0>>
  : -1 

type Arr = [1, 2, 3, 4, 5];
type I0 = IndexOf<Arr, 0>; // -1
type I1 = IndexOf<Arr, 1>; // 0
type I2 = IndexOf<Arr, 3>; // 2

@jackwangwj
Copy link

// 倒序比较,相等就返回length,否则递归比较,直到为空
type IndexOf<A extends any[], Item> =
A extends [...infer Rest, infer Tail]
? Tail extends Item
? A["length"]
: IndexOf<Rest, Item>
: -1
// 你的实现代码

type Arr = [1, 2, 3, 4, 5]
type I0 = IndexOf<Arr, 0> // -1
type I1 = IndexOf<Arr, 1> // 0
type I2 = IndexOf<Arr, 3> // 2

@zjxxxxxxxxx
Copy link

type _IndexOf<A extends any[], Item, Count extends unknown[] = []> = A extends [
  infer F,
  ...infer R
]
  ? F extends Item
    ? Count["length"]
    : _IndexOf<R, Item, [...Count, 0]>
  : -1;

type IndexOf<A extends any[], Item> = _IndexOf<A, Item>;

@ChangerHe
Copy link

// 解法: 增加一个数组, 使用数组长度来指代数组下标求解
type IndexOf<A extends any[], Item, L extends any[] = []> = A extends [f: infer F, ...r: infer R] ? F extends Item ? L['length'] : IndexOf<R, Item, [...L, '']> : -1

@linkeLynn
Copy link

// 倒序比较,相等就返回length,否则递归比较,直到为空 type IndexOf<A extends any[], Item> = A extends [...infer Rest, infer Tail] ? Tail extends Item ? A["length"] : IndexOf<Rest, Item> : -1 // 你的实现代码

type Arr = [1, 2, 3, 4, 5] type I0 = IndexOf<Arr, 0> // -1 type I1 = IndexOf<Arr, 1> // 0 type I2 = IndexOf<Arr, 3> // 2

@jackwangwj 你这个最简洁,但是有个细节不对,A["length"] 应该是是 Rest["length"]

@ChuTingzj
Copy link

// 实现 IndexOf 工具类型,用于获取数组类型中指定项的索引值。若不存在的话,则返回 -1 字面量类型。具体的使用示例如下所示:
// type IndexOf<A extends any[], Item> = // 你的实现代码
// type Arr = [1, 2, 3, 4, 5]
// type I0 = IndexOf<Arr, 0> // -1
// type I1 = IndexOf<Arr, 1> // 0
// type I2 = IndexOf<Arr, 3> // 2

type IndexOf<A extends any[], Item, Flag extends any[] = []> = Item extends A[Flag['length']]
  ? Flag['length']
  : Flag['length'] extends A['length']
  ? -1
  : IndexOf<A, Item, [...Flag, A[Flag['length']]]>
type Arr = [1, 2, 3, 4, 5]
type I000 = IndexOf<Arr, 0> // -1
type I111 = IndexOf<Arr, 1> // 0
type I222 = IndexOf<Arr, 3> // 2

@dolphin0618
Copy link

dolphin0618 commented Jul 28, 2022

type IndexOf<A extends any[], Item, R extends any[] = []> = A extends [infer S, ...infer B] ? 
    Item extends S ? R['length'] : IndexOf<B, Item, [1, ...R]>
: -1

type Arr = [1, 2, 3, 4, 5]
type I0 = IndexOf<Arr, 0> // -1
type I1 = IndexOf<Arr, 1> // 0
type I2 = IndexOf<Arr, 3> // 2

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

No branches or pull requests