我希望函数返回一个与泛型类型参数类型具有相同属性名称的类型。
我试过了:
function getObjectInfo<T>(obj: T): { [key: keyof T]: any; } {
const info = {};
Object.getOwnPropertyNames(obj).forEach(propertyName => {
info[propertyName] = { /* some info object */ };
});
return info;
}
和
function getObjectInfo<T, K extends keyof T>(obj: T): { [key: K]: any; } {
const info = {};
Object.getOwnPropertyNames(obj).forEach(propertyName => {
info[propertyName] = { /* some info object */ };
});
return info;
}
但是收到以下错误
索引签名参数类型不能是联合类型。请考虑使用映射对象类型。
更新
也尝试过:
function getObjectInfo<T extends { [key: string]: any }, K extends keyof T>(obj: T): { [key: K]: any; } {
const info = {};
Object.getOwnPropertyNames(obj).forEach(propertyName => {
info[propertyName] = { /* some info object */ };
});
return info;
}
所以K不是联合类型但仍然会得到相同的错误
答案 0 :(得分:2)
正如错误所述,您可以考虑使用映射对象来执行此操作。映射对象将使用语法[key in keyof T]
而不是[key: keyof T]
,并将这些键映射到您指定的任何类型(在您的情况下为any
)。
以下是您的代码段的外观。唯一的变化是返回类型:
function getObjectInfo<T>(obj: T): { [key in keyof T]: any; } {
const info = {};
Object.getOwnPropertyNames(obj).forEach(propertyName => {
info[propertyName] = { /* some info object */ };
});
return info;
}
const x = getObjectInfo({foo: "bar"}); // x has type {foo: any}
此外,您可以使用内置的Record
类型作为另一种解决方案。 Record
类型接受两个通用参数。第一个是表示记录键的字符串联合,第二个是它们映射到的类型。因此,对于相同的结果,上述返回类型也可以替换为Record<keyof T, any>
。