打字稿中的通用对象类型
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<K, T>
,可以用代替自己定义
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)中尝试它时效果很好,你能在那里重现它吗?以上是关于打字稿中的通用对象类型的主要内容,如果未能解决你的问题,请参考以下文章