Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript interface with dynamic keys extending Object

In Typescript I am not able to make my interface extend Object when indexer is used (key as string).

If i do not extend Object then it works fine , but intellisense does not give suggestions for Object.hasOwnProperty() method.

interface MyObject extends Object {
 [key: string] : string;
}

Above code, I get compile time error as: "Property 'hasOwnProperty' of type '(v: string) => boolean' is not assignable to string index type 'string'."

Later in code i would like to use variable of type MyObject to check if it contains a particular key using hasOwnProperty method of Object.

like image 801
Indra Chatterjee Avatar asked Mar 26 '18 06:03

Indra Chatterjee


People also ask

How would you define an interface for objects with dynamic keys?

Use an index signature to define a type for an object with dynamic keys, e.g. [key: string]: string; . Index signatures are used when we don't know all of the names of a type's properties ahead of time, but know the shape of the values.

How do you create an interface for a dynamic object in TypeScript?

TypeScript allows you to specifically type an object using an interface that can be reused by multiple objects. To create an interface, use the interface keyword followed by the interface name and the typed object.

Can an interface extend a type TypeScript?

In TypeScript, interfaces can extend each other just like classes. This lets us copy the members of one interface to another and gives us more flexibility in how we use our interfaces. We can reuse common implementations in different places and we can extend them in different ways without repeating code for interfaces.


1 Answers

You don't need to extend Object to have the hasOwnProperty method. Since all objects inherit Object this method will exist on any instance of the interface.

interface MyObject {
    [key: string]: string;
}

var v: MyObject = {
    "foo" : "1"
}
v.hasOwnProperty("foo");

The index signature generally means that all members of the interface will be compatible with the return type of the index. You can get around this using union types though, but you still can't directly create such an object without Object.assign:

type MyObject  = Object & { // Object is useless but we can specify it
    [key: string]: string;
} & { // We can specify other incompatible properties
    required: boolean
}

// We can create an instance with `Object.assign`
var v: MyObject = Object.assign({
    "foo" : "1"
}, {
    required: true
});
v.hasOwnProperty("foo");
console.log(v.required);
console.log(v['bar']); 
like image 117
Titian Cernicova-Dragomir Avatar answered Oct 13 '22 17:10

Titian Cernicova-Dragomir