为什么一个接口不能分配给Record<string, unknown>?
Why can't an interface be assigned to Record<string, unknown>?
我刚刚注意到无法将接口分配给 Record<string, unknown>
(playground link):
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)
然而,当 Foo
的类型声明被省略时(playground link)也是可能的:
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo // no error here
问题:为什么两个示例之间存在差异?对我来说,变量 foo
的简化类型在两个示例中都是相同的...接口 Foo
不应该分配给 Record<string, unknwon>
吗?!
在我的理解中,Record<string, unknown>
等同于 object
,因此任何接口都应该可以分配给它。另外 https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/ban-types.md 建议使用 Record<string, unknown>
而不是 object
.
备注:第一个示例在使用 object
(playground link) or Record<string, any>
(playground link)而不是 Record<string, unknown>
时有效。
编辑:@Lesiak 在上面有正确答案。我将此留给相关答案的 link。
诚然,我在这里有点不知所云,但我正在浏览 并且我看到:
[A] big part of TypeScript's safety comes from the fact that [...] it'll only let you treat an object as a dictionary if it knows it's explicitly intended as one.
这与我的测试一致。修改您的界面以明确地将 Foo.foo
视为索引不会产生错误。 (playground link)
interface Foo {
[foo: string]: number
}
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo
这并没有完全回答您的问题,因为 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;
我刚刚注意到无法将接口分配给 Record<string, unknown>
(playground link):
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)
然而,当 Foo
的类型声明被省略时(playground link)也是可能的:
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo // no error here
问题:为什么两个示例之间存在差异?对我来说,变量 foo
的简化类型在两个示例中都是相同的...接口 Foo
不应该分配给 Record<string, unknwon>
吗?!
在我的理解中,Record<string, unknown>
等同于 object
,因此任何接口都应该可以分配给它。另外 https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/ban-types.md 建议使用 Record<string, unknown>
而不是 object
.
备注:第一个示例在使用 object
(playground link) or Record<string, any>
(playground link)而不是 Record<string, unknown>
时有效。
编辑:@Lesiak 在上面有正确答案。我将此留给相关答案的 link。
诚然,我在这里有点不知所云,但我正在浏览
[A] big part of TypeScript's safety comes from the fact that [...] it'll only let you treat an object as a dictionary if it knows it's explicitly intended as one.
这与我的测试一致。修改您的界面以明确地将 Foo.foo
视为索引不会产生错误。 (playground link)
interface Foo {
[foo: string]: number
}
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo
这并没有完全回答您的问题,因为 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;