Ste*_*lla 5 types compiler-errors object type-conversion typescript
I just noticed that an interface cannot be assigned to 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)
Run Code Online (Sandbox Code Playgroud)
However the same is possible, when the type declaration for Foo is omitted (playground link):
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo // no error here
Run Code Online (Sandbox Code Playgroud)
Question: Why is there a difference between both examples? For me the reduced type of the variable foo is the same in both examples... Shouldn't the interface Foo be assignable to Record<string, unknwon>?!
In my understanding Record<string, unknown> is equivalent to object and thus any interface should be assignable to it. Also https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/ban-types.md suggests using Record<string, unknown> instead of object.
Remarks: The first example works when either object (playground link) or Record<string, any> (playground link) is used instead of Record<string, unknown>.
您遇到过类型中缺少索引签名(仅在接口上,而不是在类型别名上)#15300
当您将接口更改为类型时,代码将起作用:
type Foo = {
foo: number
}
const foo: Foo = { foo: 1 };
const bar: Record<string, unknown> = foo;
Run Code Online (Sandbox Code Playgroud)
编辑:@Lesiak 上面有正确的答案。我将其保留只是为了相关答案的链接。
诚然,我有点超出了我的深度,但我正在查看这个答案,我发现:
[A] TypeScript 安全性的很大一部分来自于这样一个事实:[...] 只有当它知道它明确打算作为字典时,它才会让您将对象视为字典。
这与我的测试一致。修改您的接口以显式地将Foo.foo其视为索引不会产生错误。(游乐场链接)
interface Foo {
[foo: string]: number
}
const foo = { foo: 1 }
const bar: Record<string, unknown> = foo
Run Code Online (Sandbox Code Playgroud)
这并不能完全回答您的问题,因为Record<string, any>与您的显式界面一起工作,但也许知识渊博的人可以从这里获取它。
| 归档时间: |
|
| 查看次数: |
1988 次 |
| 最近记录: |