提问人:Stephan Kulla 提问时间:1/20/2021 最后编辑:Jerryh001Stephan Kulla 更新时间:11/17/2023 访问量:27456
为什么不能将接口分配给 Record<string, unknown>?
Why can't an interface be assigned to Record<string, unknown>?
问:
我刚刚注意到无法将接口分配给(游乐场链接):Record<string, unknown>
interface Foo {
foo: number
}
const foo: Foo = { foo: 1 }
const bar: Record<string, unknown> = foo
// |-> Error: Type 'Foo' is not assignable to type 'Record<string, unknown>'
// Index signature is missing in type 'Foo'.(2322)
但是,当省略类型声明时,同样的情况是可能的(playground 链接):Foo
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo // no error here
问题:为什么两个例子之间有区别?对我来说,变量的简化类型在两个示例中是相同的......接口不应该分配给吗?foo
Foo
Record<string, unknown>
在我的理解中,它等价于,因此任何接口都应该分配给它。此外,@typescript-eslint/ban-types 建议使用 代替 .Record<string, unknown>
object
Record<string, unknown>
object
言论:第一个示例在使用 (playground link) 或 (playground link) 而不是 时起作用。object
Record<string, any>
Record<string, unknown>
答:
编辑:@Lesiak上面有正确答案。我把它留给相关答案的链接。
诚然,我在这里有点不知所措,但我正在浏览这个答案,我看到:
TypeScript 的安全性很大程度上来自于这样一个事实,即 [...] 它只允许你将一个对象视为字典,如果它知道它明确地打算作为一个字典。
这与我的测试一致。修改接口以显式视为索引不会产生错误。(游乐场链接Foo.foo
)
interface Foo {
[foo: string]: number
}
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo
这并不能完全回答您的问题,就像您的显式界面一样,但也许知识渊博的人可以从这里获取它。Record<string, any>
评论
interface Foo { foo: number, [key: string]: unknown }
foo
number
Record<string, any>
您遇到 Index signature is missing in type (only on interfaces, not on type alias) #15300
当您将接口更改为类型时,该代码将起作用:
type Foo = {
foo: number
}
const foo: Foo = { foo: 1 };
const bar: Record<string, unknown> = foo;
评论