Reputation: 5656
In typescript is there any way to assign a variable a generic object type. Here's what I mean by 'generic Object type'
let myVariable: GenericObject = 1 // Should throw an error
= 'abc' // Should throw an error
= {} // OK
= {name: 'qwerty'} //OK
i.e. It should only allow javascript objects to be assigned to the variable and no other type of data(number, string, boolean)
Upvotes: 89
Views: 132308
Reputation: 2477
Answer:
From ESLint hint:
object
.So the alternative is:
type GenericObject = object;
Or just use object
directly where its needed. Note that letter casing is crucial since the Object
type signifies "any non-nullish value" and might be discouraged.
Bonus:
This solution: type GenericObject = { [key: string]: unknown };
might not be the best option if you have a class data structure as it might lead to the errors:
Argument of type 'DummyClass' is not assignable to parameter of type 'GenericObject'.
Index signature for type 'string' is missing in type 'DummyClass'
Upvotes: 1
Reputation: 560
As of TypeScript 3.0+ this is the type-safe answer:
type GenericObject = Record<string, unknown>;
And since you'll be getting type protection, you need to do a type check before using a property of the object:
const obj: GenericObject = {
someFn: () => 'string return';
}
if (typeof obj.someFn === 'function') {
obj.someFn();
}
TypeScript will not complain about any
of course but it is technically not the "generic object type".
More info on the differences between any
and unknown
:
Upvotes: 5
Reputation: 237
A bit of a tangent since I haven't found a similar answer elsewhere, from @JaredMcAteer here, using record
helped me with mixing enums + objects.
enum FOO_ENUM {
BAR = 'BAZ';
}
type FOO_OBJECT_TYPE = { ... };
const BIZ_OBJECT: Record<FOO_ENUM, FOO_OBJECT_TYPE> = {
[FOO_ENUM.BAR]: { ... }
}
Where before I was typing BIZ_OBJECT
as
BIZ_OBJECT: {[type: string]: FOO_OBJECT}
which allowed something like BIZ_OBJECT.asd
, now only a key from FOO_ENUM
can be used, e.g.
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 !
Upvotes: 0
Reputation: 22545
Typescript 2.1+ also has has a utility type, Record<K, T>
, you can use instead of making your own definition
const myObj: Record<string, any>;
I like to use the style described in top answer when I can give a meaningful name to key
but if it's not really as obvious or necessary Record
is a great option.
Upvotes: 90
Reputation: 342
As of TypeScript 2.2 you can use
let myVariable: object;
Edit: Here's an example:
let myVariable: object = { fun: 1 };
Upvotes: -1
Reputation: 164357
Sure thing:
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
Upvotes: 121