I'm trying to create typing for an object that has a structure like this:
{
"1bcc10d3-425e-4a91-9a90-d7f2969986f9": {
result: {
key: "value"
}
},
another_key: ["test", "12345"]
}
In the example above, "1bcc10d3-425e-4a91-9a90-d7f2969986f9" is an arbitrary UUID that is being used as a key. My object can have one or more such records, indexed by a UUID, and it also has a few other keys of various types.
I have tried a few different representations, none of which have worked. The most obvious would be something like this:
interface MyResultType {
[uuid: string]: {
result: {
key: string;
}
};
another_key: string[];
}
That doesn't work however, as I get the following error:
Property 'another_key' of type 'string[]' is not assignable to 'string' index type '{ result: { key: string; }; }'.ts(2411)
My understanding is that the problem here is that [uuid: string]
matches any key of type string, so it's trying to assign another_key
to the {result: {key: string;}}
type.
So I tried using an intersection type:
type MyResultType = {
[uuid: string]: {
result: {
key: string;
};
};
} & {
another_key: string[];
};
This time, the declaration works fine, but it fails when I try to use it:
const result: MyResultType = {
'1bcc10d3-425e-4a91-9a90-d7f2969986f9': {
result: {
key: 'value',
},
},
another_key: ['test', '12345'],
};
Results in this error:
Type '{ '1bcc10d3-425e-4a91-9a90-d7f2969986f9': { result: { key: string; }; }; another_key: string[]; }' is not assignable to type 'MyResultType'.
Type '{ '1bcc10d3-425e-4a91-9a90-d7f2969986f9': { result: { key: string; }; }; another_key: string[]; }' is not assignable to type '{ [uuid: string]: { result: any; }; }'.
Property 'another_key' is incompatible with index signature.
Property 'result' is missing in type 'string[]' but required in type '{ result: any; }'.ts(2322)
I tried rephrasing it like this:
type MyResultType = {
[uuid: Omit<string, 'another_key'>]: {
result: any;
};
} & {
another_key: string[];
};
But that still doesn't work:
An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type.ts(1268)
Is there any way to do what I'm trying to do?