使用字符串变量作为属性名称的动态类型
我希望能够使用作为指定参数之一的属性名称动态构造类型.虽然我可以构造实际的对象,但我似乎无法构造实际的类型.我想使用这种类型进行组合更改
I would like to be able to construct a type dynamically with a property name which is one of the specified parameters. While I can construct the actual object, I cannot seem to construct the actual type. I would like to use this type for composition alter
export function mapProp<AssignedType>(value: AssignedType, propertyName: string) {
type ReturnType = {
[propertyName]: value
}; // errors on this line
return {
[propertyName]: value
};
}
发出的错误如下:
类型字面量中的计算属性名称必须引用表达式其类型是文字类型或唯一符号"类型.
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
我认为你最接近的是这样的:
I think the closest you're going to get is something like this:
export function mapProp<PropertyName extends string, AssignedType>(
value: AssignedType,
propertyName: PropertyName
) {
type ReturnType = {
[K in PropertyName]: AssignedType
};
// equivalent to Record<PropertyName, AssignedType>
return {
[propertyName]: value
} as ReturnType;
}
在这种情况下,您将使用映射类型 而不是带有 索引签名的类型.PropertyName
泛型类型参数的添加允许将键缩小到 string
之后,如果您将它传递给字符串文字:
In this case you'd be using a mapped type instead of a type with an index signature. The addition of the PropertyName
generic type parameter allows the narrowing of the key past string
, if you pass it a string literal:
const thing = mapProp(123, "abc");
thing.abc; // number
thing.def; // error
在这种情况下,ReturnType
已知等同于 {abc: number}
.如果您只知道编译时键是 string
,那么您会得到:
In that case ReturnType
is known to be equivalent to {abc: number}
. If all you know is that the key is a string
at compile time, then you get this:
declare const propName: string;
const stuff = mapProp(123, propName);
stuff.abc; // number
stuff.def; // number
现在 ReturnType
等价于 {[k: string]: number}
,这意味着它接受任何 string
键(并给它一个number
值).这可能不是您想要的,但这是编译器在这种情况下所能做的最好的事情.
Now ReturnType
is equivalent to {[k: string]: number}
, meaning it accepts any string
key (and gives it a number
value). This might not be what you want, but it's the best the compiler can do in this case.
另请注意,如果不使用类型断言(as ReturnType
),计算属性通常会以字符串索引而不是更具体的形式结束.这是目前 TypeScript 的设计限制.已经有一些尝试来解决这个问题,但还没有任何东西进入语言.
Also note that without using a type assertion (as ReturnType
), computed properties usually end up as string indexes instead of something more specific. This is currently a design limitation of TypeScript. There have been some attempts to deal with this, but nothing has made it into the language yet.
希望有所帮助;祝你好运!
Hope that helps; good luck!