首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型‘Object’. is (2322)中缺少“string”类型的索引签名

类型‘Object’. is (2322)中缺少“string”类型的索引签名
EN

Stack Overflow用户
提问于 2022-02-05 12:25:01
回答 2查看 1.6K关注 0票数 2

我希望将我的自定义对象分配给在Prisma包中实现的JsonObject。这段代码会产生错误,我不知道为什么:

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-05 12:50:07

首先,不要将自定义对象命名为ObjectObject类型是为Object值构建的类型。这可能会让人迷惑。我不确定您是想更新现有的Object类型,还是只想创建一些自定义类型,这对于接口来说非常重要,因为声明合并的存在。

考虑一下这个例子:

代码语言:javascript
复制
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已被索引。换句话说,它意味着您可以使用任何字符串来访问对象值。例如:

代码语言:javascript
复制
jsonObject['hello'] // ok

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

代码语言:javascript
复制
object['hello'] // error

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

代码语言:javascript
复制
jsonObject = object;

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

因此,如果要使其可分配,则应将索引添加到CustomObject中。

代码语言:javascript
复制
interface CustomObject {
    [prop: string]: JsonValue
    name: number
}

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

代码语言:javascript
复制
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在索引方面存在差异。见我的回答文章

请记住,这一行动是允许的:

代码语言:javascript
复制
jsonObject['hello'] // undefined but allowed

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

票数 2
EN

Stack Overflow用户

发布于 2022-02-05 12:53:59

这里有几个问题。

  • Object是内置的javascript数据类型。你应该给你的接口命名其他的东西,比如MyObject
  • 您正在声明一个变量object,但它没有初始化,也就是说它没有任何值。你不能像x = object那样在操作中使用它,
  • 您的接口没有与JsonObject完全重叠。您可以修改接口或使用type
代码语言:javascript
复制
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

打字稿操场里试一试。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70997988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档