在打字稿中,有什么方法可以为变量分配通用对象类型。 这就是我所说的“通用对象类型”的含义
let myVariable: GenericObject = 1 // Should throw an error
= 'abc' // Should throw an error
= {} // OK
= {name: 'qwerty'} //OK
即它应该只允许将 javascript 对象分配给变量,而不允许其他类型的数据(数字、字符串、布尔值)
当然可以:
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
(操场上的代码)
Typescript 2.1+ 还有一个 实用类型,
Record<K, T>
,您可以使用而不是自己定义
const myObj: Record<string, any>;
当我可以给
key
起一个有意义的名称时,我喜欢使用顶部答案中描述的样式,但如果它不是那么明显或必要 Record
是一个不错的选择。
从 TypeScript 3.0+ 开始,这是类型安全的答案:
type GenericObject = Record<string, unknown>;
由于您将获得类型保护,因此您需要在使用对象的属性之前进行类型检查:
const obj: GenericObject = {
someFn: () => 'string return';
}
if (typeof obj.someFn === 'function') {
obj.someFn();
}
TypeScript 当然不会抱怨
any
,但从技术上讲它不是“通用对象类型”。
有关
any
和 unknown
之间差异的更多信息:
从 TypeScript 2.2 开始,您可以使用
let myVariable: object;
编辑:这是一个例子:
let myVariable: object = { fun: 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 !
答案:
来自 ESLint 提示:
object
。所以我的建议是:
type GenericObject = object;
或者直接在需要的地方使用
object
。请注意,字母大小写至关重要,因为 Object
类型表示“任何非空值”,因此可能不鼓励使用。
奖金:
如果您有类数据结构,则此解决方案:
type GenericObject = { [key: string]: unknown };
可能不是最佳选择,因为它可能会导致错误:
“DummyClass”类型的参数不可分配给以下参数 输入“通用对象”。
类型中缺少“字符串”类型的索引签名 '虚拟类'