我希望能够返回一个对象数组,其键名将取决于函数接收的参数。我有以下内容:
class CountryFilterFormatterService {
public groupCountriesByRegion(
groupLabelKey: string,
groupValuesKey: string,
): {[groupLabelKey]: string, [groupValuesKey]: string}[] {
return [
{
[groupLabelKey]: 'foo',
[groupValuesKey]: 'bar'
}
]
}
}
export default CountryFilterFormatterService;
我希望函数groupCountriesByRegion
的返回类型为{[groupLabelKey as string]: string, [groupValuesKey]: Country[]}[]
,但出现以下错误:A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type
如何实现这种返回类型?
答案 0 :(得分:0)
这个怎么样?由于要提供动态键,因此只能指定一次。如果您有一组固定的键,则还可以创建一个Enum并将其用于通用string
class CountryFilterFormatterService {
public groupCountriesByRegion(
groupLabelKey: string,
groupValuesKey: string,
): {[groupLabelKey: string]: string}[] {
return [
{
[groupLabelKey]: 'foo',
[groupValuesKey]: 'bar'
}
]
}
}
export default CountryFilterFormatterService;
答案 1 :(得分:0)
我的建议是使函数generic的类型为groupLabelKey
和groupValuesKey
,如下所示:
class CountryFilterFormatterService {
public groupCountriesByRegion<LK extends string, VK extends string>(
groupLabelKey: LK,
groupValuesKey: VK,
): { [K in LK | VK]: string }[] {
return [
{
[groupLabelKey]: 'foo',
[groupValuesKey]: 'bar'
} as { [K in LK | VK]: string }
]
}
}
有两个通用类型参数:LK
和VK
,对应于groupLabelKey
和groupValuesKey
传递的值的(希望)string literal types分别。返回类型是mapped type,{[K in LK | VK]: string}
的数组。这意味着“对象的键为LK
和VK
,并且这些键处的值为string
s。
这里有一个折衷之处,就是编译器无法将值{ [groupLabelKey]: 'foo', [groupValuesKey]: 'bar' }
识别为正确的类型。它看到通用的计算密钥并将其扩展到string
,因此该对象的类型被推断为{ [k: string]: string }
,如果您按原样返回它,编译器将抱怨。与此相关的还有一个公开的GitHub问题,microsoft/TypeScript#13948,但现在是这样。
解决方法是使用type assertion,就像我在上面所做的那样,然后在对象文字后添加as { [K in LK | VK]: string }
。还有其他解决方法,但是这种解决方法与运行时代码无关。
所以,让我们看看它是否有效:
const x = (new CountryFilterFormatterService()).groupCountriesByRegion("baz", "qux");
// const x: { baz: string; qux: string; }[]
x.forEach(
v => console.log(v.baz.toUpperCase() + " " + v.qux.toUpperCase())
); // FOO BAR
看起来不错。我传入了"baz"
和"qux"
,编译器认为x
的类型为Array<{baz: string, qux: string}>
,这可能是您想要的。
好的,希望能有所帮助;祝你好运!