Let's say I want to create an interface to describe this type of objects:
let myObj= {
"count": 3,
"key1": "foo",
"key2": "bar",
"key3": "baz"
};
Those object always have a property count of type number and the rest of the properties are strings
If I define my interface using index signatures like this:
interface MyObect {
count: number;
[key: string]: string;
}
I got the compiler error:
[ts] Property 'count' of type 'number' is not assignable to string index type 'string'.
So I have to define it like this:
interface MyObect {
count: number;
[key: string]: any;
}
But this definition is not as presise.
Is there a way to enforce the type of extra properties ?
I've achieved something like this by using an intersection type:
type MyObject =
{
count : number
} & {
[key : string] : string
}
This works (I am using TypeScript 2.3.2) for consuming an object, as follows
// x : MyObject
const count : number = x.count;
const foo : string = x.foo
but as pointed out, this assignment still fails
const x : MyObject = {
count: 10,
foo: 'bar'
}
so this may be of use only in some cases.
This question has appeared in lots of subtly different forms over the past two months. Usually as a combination of a dictionary and an array.
As an alternative, you can use an error supression to keep the simplest definition of the type, which the TypeScript compiler is actually perfectly capable of working with.
It uses an error supression comment, which is generally a bad thing. It also requires a small additional effort at initialisation. The rest of the usage is as you would expect.
Here is a spin through your specific example using the dictarry technique.
interface MyObject {
[key: string]: string;
// @ts-ignore: I'm creating a Dictarray!
count: number;
}
let myObj = { count: 0 } as MyObject;
myObj.key1 = "a string";
myObj.count = 4;
// Error, 1 is not a string - as you'd expect
myobj.key2 = 1;
myObj = {
"count": 3,
"key1": "foo",
"key2": "bar",
"key3": "baz"
} as unknown as MyObject;
const str = myObj.key1;
const num = myObj.count;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With