Typescrip类型体操 - IndexOf

题目

中文

实现类型版本的 Array.indexOf, indexOf<T, U> 接受一个数组Tany类型的U作为参数, 返回T中第一个U的索引

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

English

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

答案

注释中包含了部分解析

// ✅
type IsEqual<X, Y> = (<F>() => F extends X ? 1 : 0) extends <F>() => F extends Y ? 1 : 0
// `IsEqual`的错误写法
// ❌`IsEqualMistake<any, string>`期望返回`true`, 实际是`boolean`, 发生了`distribute`
type IsEqualMistake<L, R> = L extends R ? (R extends L ? true : false) : false;
type IsEqualMistake1<L, R> = [
    L extends R ? 1 : 0,
    R extends L ? 1 : 0
] extends [1, 1]
    ? true
    : false;
// ❌ 另一种写法错误写法
// 虽然是错误写法, 但是有个知识点:
// 💡 使用`[]`可以防止发生[`distribute`](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types)
type IsEqualMistake2<L, R> = [Exclude<L, R>, Exclude<R, L>] extends [
    never,
    never
]
    ? true
    : false;
type IndexOf<T extends any[], U extends any, S extends any[] = []> = T extends [
    infer L,
    ...infer R
]
    ? true extends IsEqual<L, U>
        ? S['length']
        : IndexOf<R, U, [...S, 0]>
    : -1;

在线演示

posted @ 2022-10-25 01:43  Laggage  阅读(54)  评论(0编辑  收藏  举报