类型"对象"中缺少类型 'string' 的索引签名.ts(2322)



我想将我的自定义对象分配给Prisma包中的JsonObject efied。这段代码产生了错误,我不知道为什么:

interface JsonArray extends Array<JsonValue> {}
type JsonValue = string | number | boolean | JsonObject | JsonArray | null
type JsonObject = {[Key in string]?: JsonValue}
// ^ These are defined in Prisma package and I cannot change them
interface Object {
name: string
}
let object : Object
let jsonObject : JsonObject 
// This line has error
jsonObject = object;
// Type 'Object' is not assignable to type 'JsonObject'.
// The 'Object' type is assignable to very few other types.
// Did you mean to use the 'any' type instead?
// Index signature for type 'string' is missing in type 'Object'.ts(2322)

首先,不要将自定义对象类型命名为Object。类型Object内置于Object值的类型中。它可能会使人们感到困惑。我不确定您是想更新现有的Object类型,还是只想创建一些自定义类型,这对接口很重要,因为声明合并。

考虑这个例子:

interface JsonArray extends Array<JsonValue> { }
type JsonValue = string | number | boolean | JsonObject | JsonArray | null
type JsonObject = { [Key in string]?: JsonValue }
interface CustomObject {
name: string
}
declare let object: CustomObject
declare let jsonObject: JsonObject
// This line has error
jsonObject = object;

您的错误意味着jsonObject已编入索引。换句话说,这意味着您可以使用任何字符串来访问对象值。例如:

jsonObject['hello'] // ok

而对于CCD_ 6则不是这样。在object的情况下,只允许使用name密钥来访问适当的值。您不允许使用hello

object['hello'] // error

现在,想象一下TS允许您执行以下操作的情况:

jsonObject = object;
jsonObject['hello'] // undefined, because  it has only `name` property

所以,如果你想让它可分配,你应该添加索引到你的CustomObject:

interface CustomObject {
[prop: string]: JsonValue
name: number
}

或者,更有趣的是使用type关键字声明CustomObject而不是interface:

interface JsonArray extends Array<JsonValue> { }
type JsonValue = string | number | boolean | JsonObject | JsonArray | null
type JsonObject = { [Key in string]?: JsonValue }
type CustomObject= {
name: number
}
declare let object: CustomObject
declare let jsonObject: JsonObject
jsonObject = object; // no error
jsonObject.name

是的,interfacetype在索引方面存在差异。查看我的答案和文章

请记住,此操作是允许的:

jsonObject['hello'] // undefined but allowed

没有编译器错误,但它是不安全的。

这里有一些问题。

  • Object是一个内置的javascript数据类型。您应该为接口命名其他名称,例如MyObject
  • 您正在声明一个变量object,但它没有初始化,即它没有任何值。您不能在类似x = object的操作中使用它
  • 您的界面与JsonObject没有完全重叠。您可以修改接口,也可以使用type
interface JsonArray extends Array<JsonValue> {}
type JsonValue = string | number | boolean | JsonObject | JsonArray | null
type JsonObject = {[Key in string]?: JsonValue}
// ^ These are defined in Prisma package and I cannot change them
type MyObject = {
name: string
}
let anObject: MyObject = {name: "foo"}
let jsonObject: JsonObject 
// no error
jsonObject = anObject

在打字游戏场试试。

相关内容

  • 没有找到相关文章

最新更新