使用字符串变量作为属性名称的动态类型 [英] Dynamic type using a string variable as a property name

查看:35
本文介绍了使用字符串变量作为属性名称的动态类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够使用作为指定参数之一的属性名称动态构造类型.虽然我可以构造实际的对象,但我似乎无法构造实际的类型.我想使用这种类型进行组合更改

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.

示例游乐场:http://www.typescriptlang.org/play/#src=%0D%0Aexport%20function%20mapProp%3CAsignedType%3E(value%3A%20AssignedType%2C%20propertyName%3A%20string)%20%7B%0D%0A%0D%0A%20%20type%20ReturnType%20%3D%20%7B%0D%0A%20%20%20%20%5BpropertyName%5D%3A%20value%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20return%20%7B%0D%0A%20%20%20%20%5BpropertyName%5D%3A%20value%0D%0A%20%20%7D%3B%0D%0A%7D

推荐答案

我认为你最接近的是这样的:

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!

这篇关于使用字符串变量作为属性名称的动态类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆