Here is a type definition in TypeScript:
interface Obj {
id:string
}
I want to define a collection of Obj called ObjCollection, where the index of ObjCollection must be the same as the id field.
const objcollection: ObjCollection = {
key1: { id: "key1" },
key2: { id: "key2" },
key3: { id: "key33333" } // Error, id should be key3
}
So how should ObjCollection be defined?
>Solution :
There is no specific ObjCollection type in TypeScript that meets your requirement. You can instead define a generic type like
type ObjCollection<K extends PropertyKey> =
{ [P in K]: { id: P } }
which expresses this idea, but it depends on supplying a type argument corresponding to a set of keys. So your objcollection would be of type ObjCollection<"key1" | "key2" | "key3">. To save you from having to write that yourself, you can write a generic helper function to have the compiler infer it:
const asObjCollection = <K extends PropertyKey>(
oc: ObjCollection<K>) => oc;
Then instead of writing const objcollection: ObjCollection = {⋯}, you’d write const objcollection = asObjCollection({⋯}). It’s not the same, but it’s pretty close, and it gives you the desired behavior:
const objcollection = asObjCollection({
key1: { id: "key1" },
key2: { id: "key2" },
key3: { id: "key33333" } // error!
});