【发布时间】:2019-12-04 02:34:51
【问题描述】:
在 Typescript 中,以下似乎应该完成所需类型的创建:
interface RecordX extends Record<string, string[]> {
id: string
}
但这抱怨:
“string”类型的属性“id”不能分配给字符串索引类型“string[]”。 ts(2411)
如何将不同类型的属性添加到Record<> 实用程序类型?
细节和一般案例+样本
一般来说,如何描述具有异质值类型固定属性但动态添加的同质值类型属性的对象。
S,例如给定这个对象:
const a = {
// some properties with known "hard-coded" types
id: '123',
count: 123,
set: new Set<number>(),
// and some dynamic properties
dynamicItemList: ['X', 'Y']
anotherDynamicallyAddedList: ['Y', 'Z']
} as ExtensibleRecord
那么如何定义一个类型或接口ExtensibleRecord where:
-
id、count和set的类型和属性键固定为string、number和Set<number> -
dynamicItemList和anotherDynamicallyAddedList的类型以及添加到对象的任何其他属性为string[]
我尝试了许多我认为可能可行的变体,包括:
type ExtensibleRecord = {
id: string, count: number, set: Set<number>
} & Record<string, string[]>
type ExtensibleRecord = {
id: string, count: number, set: Set<Number>
} & Omit<Record<string, string[]>, 'id'|'count'|'set'>
interface ExtensibleRecord = {
id: string,
count: number,
set: Set<number>,
[k: string]: string[]
}
但每个似乎都会导致错误。
这感觉很常见且显而易见,但我找不到示例或参考。
playground
【问题讨论】:
-
Record<string, string[]>表示id属性(如果存在)必须是string[]。你不能用不匹配的东西来扩展它;你试图做一个例外,而不是一个扩展,并且 TypeScript 不(还)支持它作为一个具体的类型。如果您想获得关于如何操作的建议,您可能希望扩展您的用例。请确保您的代码是minimal reproducible example;现在,与Record的名称冲突正在掩盖您的问题。 -
@jcalz 添加了更多描述 + MWE
-
原因是 TypeScript 试图在对象字面量方面做得更多。这样做是为了避免明显的错误。因此,如果在对象字面量构造之后添加动态属性,它将起作用。
标签: typescript