如何使用可变键初始化 TypeScript 接口

huangapple go评论76阅读模式
英文:

how to initialize a typescript interface with a variable key

问题

请看以下代码:

function createObj(key: string, value: unknown) {
  const obj = {};
  obj[key] = value;
  return obj;
}

出现错误:

TS7053:元素隐式具有“any”类型,因为类型为“string”的表达式不能用于索引类型为“{}”的类型。在类型“{}”上找不到具有参数类型“string”的索引签名。

我知道可以这样写:

const obj = {} as Record<string, unknown>;

但我想知道是否可以在一条语句中初始化对象,例如:

const obj = {
  key: value
};

这不起作用,因为这里的key是一个字符串文字,而不是变量key的值。

英文:

See the following code:

function createObj(key: string, value:unknown) {
  const obj = {};
  obj[key] = value;
  return obj;
}

gives error:

> TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.   No index signature with a parameter of type 'string' was found on type '{}'.

I know I could write it as

  const obj = {} as Record&lt;string, unknown&gt;;

but I wonder if I could initialize the object in one statement, like

  const obj = {
    key: value
  };

which does not work because key is a string literal here and not the value of variable key.

答案1

得分: 1

可以使用计算属性名(由另一个答案引用)如下所示:

function createObj(key: string, value: unknown) {
  return {
    [key]: value,
  };
}
英文:

One can use computed property names (referenced by another answer) as follows:

function createObj(key: string, value: unknown) {
  return {
    [key]: value,
  };
}

答案2

得分: 1

以下是您要翻译的内容:

当您即时创建文字为空的对象时,TS禁止您向其添加任何属性,因为根据推断,它应该是空的。我正在谈论这一行:

  const obj = {};

因此,为了使它符合TS的方式,您需要推断提供的参数:

function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value): Record&lt;Key, Value&gt;
function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value) {
  const obj: Partial&lt;Record&lt;Key, Value&gt;&gt; = {};
  obj[key] = value;
  return obj;
}

const result = createObj(&#39;a&#39;, 1)
result.a // number

Key - 代表了key参数的推断类型

Value - 代表了value参数的推断类型

我在obj中使用了Partial&lt;Record&lt;Key, Value&gt;&gt;类型。有关PartialRecord的信息,请参阅文档

Partial - 所有值都是可选的

Record - 代表哈希映射数据结构(JavaScript中的常规对象)

正如您可能已经注意到的,result.a 推断为一个数字。

我们可以做得更好。只需添加类型Json

type Json =
  | null
  | undefined
  | string
  | number
  | Array&lt;Json&gt;
  | { [prop: string]: Json }

function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value): Record&lt;Key, Value&gt;
function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value) {
  const obj: Partial&lt;Record&lt;Key, Value&gt;&gt; = {};
  obj[key] = value;
  return obj;
}

const result = createObj(&#39;a&#39;, 1)
result.a // 1

现在,result.a1

英文:

WHen you create literal empty object on the fly, TS forbids you to add any properties to it, because according to inference, it should be empty. I am talking about this line:

  const obj = {};

Hence, in order to make it in TS way, you need to infer provided arguments:


function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value): Record&lt;Key, Value&gt;
function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value) {
  const obj: Partial&lt;Record&lt;Key, Value&gt;&gt; = {};
  obj[key] = value;
  return obj;
}

const result = createObj(&#39;a&#39;, 1)
result.a // number

Key - represents infered type of key argument

Value - represents infered type of value argument

I used Partial&lt;Record&lt;Key, Value&gt;&gt; type for obj. For Partial and Record see docs.

Partial - all values are optional

Record - represents a hash map data structure (regular object in javascript)

As you might have noticed, result.a infered as a number.

We can do better. Just add type Json:

type Json =
  | null
  | undefined
  | string
  | number
  | Array&lt;Json&gt;
  | { [prop: string]: Json }

function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value): Record&lt;Key, Value&gt;
function createObj&lt;Key extends PropertyKey, Value&gt;(key: Key, value: Value) {
  const obj: Partial&lt;Record&lt;Key, Value&gt;&gt; = {};
  obj[key] = value;
  return obj;
}

const result = createObj(&#39;a&#39;, 1)
result.a // 1

Now, result.a is 1

huangapple
  • 本文由 发表于 2023年1月9日 15:38:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75054303.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定