类型函数中的嵌套泛型

Nested generics in typings function

这个问题是关于 .d.ts 作为 .js 个文件的声明。

我正在尝试声明一个在泛型中包含泛型的函数,但我似乎做错了。该函数本质上是对象 ({[key: string]: E}).

Array#forEach 函数

我尝试了以下方法,但 VSCode 智能感知似乎无法理解对象的 属性 值的类型。

打字文件:

export module Util {
    export function forEach<K, T extends { [key: string]: K }>(obj: T, callbackfn: (value: K, key: string, object: T) => void): void;
}

JavaScript 通话:

if (undefined) var { Util } = require("./globals");
/** @type {{ [key:string]: number }} */
var obj = {};
Util.forEach(obj, function (value, key, object) { });

forEach的源代码:

function forEach(obj, callbackfn) {
    if (!(obj instanceof Object)) throw Error("Util.forEach called on non object");
    for (var key in obj) callbackfn.call(obj, obj[key], key, obj);
}

我对你的代码没有任何问题。如您所见,在 JS 文件和 TS 文件中导入时,对象属性类型显示正确:

使用 Visual Studio 代码 1.43.1 和 Node.js 13.11.0

进行测试

我已将代码上传到这里:https://github.com/Guerric-P/typescript-test

编辑:

现在我明白了你的实际问题,下面是你的做法:

export module Util {
    export function forEach<T, T1 extends keyof T, T2 extends T[keyof T]>(obj: T, callbackfn: (value: T2, key: T1, object: T) => void): void;
}

给出以下内容:

如果您想了解为什么密钥类型是 string | number 而不是 string 的更多详细信息,请查看此问题:

你真正想做的是:

export function forEach<T extends object>(obj: T, callbackfn: (value: T[keyof T], key: keyof T, object: T) => void): void {
  if (!(obj instanceof Object)) throw Error("Util.forEach called on non object");
  for (var key in obj) callbackfn.call(obj, obj[key], key, obj);
}

const a = {
  test: 1,
  test2: 2,
  test3: 'me'
};

forEach(a, (value, key, obj) => {})

您只需要 1 个通用参数!您可以从中推断出其余类型

这甚至适用于更严格的类型:

更新: 添加d.ts 文件:

export module Util {
  export function forEach<T extends object>(obj: T, callbackfn: (value: T[keyof T], key: keyof T, object: T) => void): void
}