首页 > 解决方案 > 不能将特定对象类型键入为记录?

问题描述

我想为通用表行定义一个接口,基本上它是任何对象,仅限于属性值作为原始类型。

但是当我尝试将特定类型的对象分配给行时,它会失败。为什么?以及如何让它发挥作用?我想强制行只能是具有原始属性值的对象。

操场

// Table row
export type Row = Record<string, string | number | undefined>

// User
interface User { name: string }
const jim: User = { name: 'Jim' }
const row: Row = jim // <== Error

错误

Type 'User' is not assignable to type 'Row'.
  Index signature for type 'string' is missing in type 'User'.

标签: typescript

解决方案


接口可以扩展。在没有索引类型限制的情况下,可以存储在用户类型变量中的扩展用户的对象可能具有其他属性。

// User
interface User { name: string }
interface FooUser extends User { foo(): void; }
const jim: FooUser = { name: 'Jim', foo() {} }
const jimAsUser: User = jim;
const row: Row = jim;  // fails as it should:
                       // foo is not a string, number, or undefined!

请注意,如果您使用type而不是interface则更安全:不需要子接口中的额外属性。也就是说,Typescript 确实允许这样做,即使它不应该这样做。type并且interface有一些细微的细节,TypeScript 手册提到了这些细节(尽管没有涉及到这个特殊情况)。

// UserAsType
type UserAsType = { name: string };
const jimAsType: UserAsType = { name: 'Jim' }
const jimAsTypeFromFooUser: UserAsType = jim;  // this *should* fail
const row2: Row = jimAsType

游乐场链接


推荐阅读