打字稿中的通用对象类型

Posted

技术标签:

【中文标题】打字稿中的通用对象类型【英文标题】:Generic Object type in typescript 【发布时间】:2017-03-31 04:43:15 【问题描述】:

在打字稿中是否有任何方法可以为变量分配通用对象类型。 这就是我所说的“通用对象类型”

let myVariable: GenericObject = 1 // Should throw an error
                              = 'abc' // Should throw an error
                              =  // OK
                              = name: 'qwerty' //OK

即它应该只允许将 javascript 对象分配给变量,而不允许其他类型的数据(数字、字符串、布尔值)

【问题讨论】:

【参考方案1】:

有点切线,因为我在其他地方没有找到类似的答案,来自@JaredMcAteer 这里,使用record 帮助我混合枚举+对象。

enum FOO_ENUM 
  BAR = 'BAZ';


type FOO_OBJECT_TYPE =  ... ;

const BIZ_OBJECT: Record<FOO_ENUM, FOO_OBJECT_TYPE> = 
  [FOO_ENUM.BAR]:  ... 

在我输入 BIZ_OBJECT 之前在哪里BIZ_OBJECT: [type: string]: FOO_OBJECT 允许BIZ_OBJECT.asd 之类的东西,现在只能使用来自FOO_ENUM 的密钥,例如

BIZ_OBJECT.BAZ // ... BIZ_OBJECT.asd // Property 'asd' does not exist on type ... BIZ_OBJECT[FOO_ENUM.BAR] // ... BIZ_OBJECT[FOO_ENUM.asd] // Property 'asd' does not ... BIZ_OBJECT[FOO_ENUM['asd']] // ! not caught !

【讨论】:

除此之外,我建议您将类型命名为FooObjectType,将枚举命名为FooEnum。我个人觉得ALL_CAPS 的类型名称太吵了。【参考方案2】:

Typescript 2.1+ 也有utility type,Record&lt;K, T&gt;,可以用代替自己定义

const myObj: Record<string, any>;

当我可以给key 起一个有意义的名字时,我喜欢使用最佳答案中描述的风格,但如果它不是很明显或没有必要,Record 是一个不错的选择。

【讨论】:

【参考方案3】:

从 TypeScript 2.2 开始,您可以使用

let myVariable: object;

编辑:这是一个例子:

let myVariable: object =  fun: 1 ;

【讨论】:

这不起作用例如:const me: object = ; me.fun = 1 将抛出错误。 Property 'fun' does not exist on type 'object'. 但是你可以这样做let myVariable: object = fun: 1 ;,这是 OP 要求的。 内置的object 类型也没有定义索引签名,所以它不是通用对象的一个​​很好的占位符,很遗憾。 @BillBarnes 没有人创建一个对象将其留空,OP 在第 3 行显示一个空对象,因此这不是 OP 所要求的。 不要为此使用object。它存在的原因不同:删除原语:youtube.com/watch?v=0y5hhzuQjCA【参考方案4】:

确定:

type GenericObject =  [key: string]: any ;

let myVariable1: GenericObject = 1; // Type 'number' is not assignable to type ' [key: string]: any; '
let myVariable2: GenericObject = 'abc'; // Type 'string' is not assignable to type ' [key: string]: any; '
let myVariable3: GenericObject =  // OK
let myVariable4: GenericObject = name: 'qwerty' //OK

(code in playground)

【讨论】:

至少在 TS 4.1.3 上,当我尝试将其传递给 new Proxy() 时,我收到错误 TS2345: Argument of type 'GenericObject' is not assignable to parameter of type 'object'.。有什么想法吗? @Romasato 当我在 ts 操场(ts 4.1.2)中尝试它时效果很好,你能在那里重现它吗?

以上是关于打字稿中的通用对象类型的主要内容,如果未能解决你的问题,请参考以下文章

打字稿中具有通用键的对象

对象打字稿中的条件类型

通用类型(T)与打字稿中的任何类型有啥区别

打字稿中对象文字的类型安全合并

如何将方法的泛型类型限制为打字稿中的对象?

从打字稿中的对象获取特定类型的所有键[重复]