typesctipt类型推断的问题?

interface F<T> {
  (
    i: T extends Array<any> ? number : keyof T,
    v: T extends Array<infer I> ? I : T[keyof T],
    t: T
  ): void | false;
}
function each<T>(target: T, callback: F<T>) {
  if (Array.isArray(target)) {
    for (let i = 0; i < target.length; i += 1) {
    // Argument of type 'number' is not assignable to parameter of type 'T extends any[] ? number : keyof T'.
      callback(i, target[i], target);
    }
  } else {
    for (const key in target) {
    // Argument of type 'Extract<keyof T, string>' is not assignable to parameter of type 'T extends any[] ? number : keyof T'.
  Type 'string & keyof T' is not assignable to type 'T extends any[] ? number : keyof T'.
      callback(key, target[key], target);
    }
  }
}
(target假设只会是数组或者对象)

在执行callback回调的时候,第一个参数ikey都会提示对应的错误,错误信息在代码的注释中,请问这是为什么呢?如果要修改要怎么样去修改呢?

阅读 1.3k
1 个回答

此问题你可能需要Function Overloading 大致如下:

interface Iterator<T> {
  (
    i: T extends Array<any> ? number : keyof T,
    v: T extends Array<infer I> ? I : T[keyof T],
    t: T
  ): void | false;
}
function each<T extends object>(target: T, iteratee?: Iterator<T>): void;
function each<T extends any[]>(target: T, iteratee?: Iterator<T>): void;
function each(target: any, iteratee: any) {
  if (Array.isArray(target)) {
    for (let i = 0; i < target.length; i += 1) {
      // Argument of type 'number' is not assignable to parameter of type 'T extends any[] ? number : keyof T'.
      iteratee(i, target[i], target);
    }
  } else {
    for (const key in target) {
      // Argument of type 'Extract<keyof T, string>' is not assignable to parameter of type 'T extends any[] ? number : keyof T'.
      iteratee(key, target[key], target);
    }
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进