英文:
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<string, unknown>;
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<Key extends PropertyKey, Value>(key: Key, value: Value): Record<Key, Value>
function createObj<Key extends PropertyKey, Value>(key: Key, value: Value) {
const obj: Partial<Record<Key, Value>> = {};
obj[key] = value;
return obj;
}
const result = createObj('a', 1)
result.a // number
Key
- 代表了key
参数的推断类型
Value
- 代表了value
参数的推断类型
我在obj
中使用了Partial<Record<Key, Value>>
类型。有关Partial
和Record
的信息,请参阅文档。
Partial
- 所有值都是可选的
Record
- 代表哈希映射数据结构(JavaScript中的常规对象)
正如您可能已经注意到的,result.a
推断为一个数字。
我们可以做得更好。只需添加类型Json
:
type Json =
| null
| undefined
| string
| number
| Array<Json>
| { [prop: string]: Json }
function createObj<Key extends PropertyKey, Value>(key: Key, value: Value): Record<Key, Value>
function createObj<Key extends PropertyKey, Value>(key: Key, value: Value) {
const obj: Partial<Record<Key, Value>> = {};
obj[key] = value;
return obj;
}
const result = createObj('a', 1)
result.a // 1
现在,result.a
是 1
。
英文:
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<Key extends PropertyKey, Value>(key: Key, value: Value): Record<Key, Value>
function createObj<Key extends PropertyKey, Value>(key: Key, value: Value) {
const obj: Partial<Record<Key, Value>> = {};
obj[key] = value;
return obj;
}
const result = createObj('a', 1)
result.a // number
Key
- represents infered type of key
argument
Value
- represents infered type of value
argument
I used Partial<Record<Key, Value>>
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<Json>
| { [prop: string]: Json }
function createObj<Key extends PropertyKey, Value>(key: Key, value: Value): Record<Key, Value>
function createObj<Key extends PropertyKey, Value>(key: Key, value: Value) {
const obj: Partial<Record<Key, Value>> = {};
obj[key] = value;
return obj;
}
const result = createObj('a', 1)
result.a // 1
Now, result.a
is 1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论