I have encounter a few times in multiple applications an scenario in which I don't know the properties of an object but I do know that all its properties are of a certain type.
For example:
interface Metadata {
key: string,
value: any
}
var metadata = {
someReducer: Metadata ,
anotherReducer: Metadata ,
// ...
}
In this scenario:
metadata
Metadata
is the type of all the properties of metadata
Now let's imagine that a function take the metadata object as argument:
function doSomething(metadata: any) {
// ...
}
I used any
as the type of the argument metadata but It would be great if I could let developers know that all the properties of this object must be of type Metadata
.
is there any way to create such type annotation?
interface MetadataObj {
[key: string]: Metadata
}
function doSomething(metadata: MetadataObj) {
or
type MetadataObj = {[key: string]: Metadata}
function doSomething(metadata: MetadataObj) {
or
function doSomething(metadata: {[key: string]: Metadata}) {
It is called index signature
.
I'm just sharing in case it is useful for others...
The following doesn't work:
interface Metadata {
key: string,
value: any
}
interface MetadataObj {
[key: string]: Metadata
}
// no explicitly typed!
var metadata = {
someReducer: { key: "test", value: 1 } ,
anotherReducer: { key: "test", value: 2 }
// ...
};
function doSomething(metadata: MetadataObj) {
// ...
}
doSomething(metadata);
The following works:
interface Metadata {
key: string,
value: any
}
interface MetadataObj {
[key: string]: Metadata
}
var metadata : MetadataObj = { // type annotation here is needed
someReducer: { key: "test", value: 1 } ,
anotherReducer: { key: "test", value: 2 }
// ...
};
function doSomething(metadata: MetadataObj) {
// ...
}
doSomething(metadata);
Here's a simpler test case:
type Test = { [key: string]: { prop: number } };
let a: Test = { a: { prop: 1 } }; // <-- No error
let b = { a: { prop: 1 } };
let c: Test = b; // <-- Error in 1.8.9
This seems to be a bug that may have already been fixed. It errors in 1.8.9
but not on the nightly build.
I believe it was fixed by #7029 (Implicit index signatures). It should probably be included on the next release.
@malibuzios thanks for he details :smile:
Just one question:
In this case: type Test = { [key: string]: { prop: number } };
Why do we have to name those variables? It is totally useless (if I'm wrong please enlighten me)
Wouldn't it be much better with only: type Test = { [string]: {number} };
This is pretty ok, but still few unnecessary characters: type Test = { [_: string]: { _: number } };
Most helpful comment
or
or
It is called
index signature
.