Reputation: 925
I have an object foo
interface Foo {
fooId: string;
otherStuff: any;
}
Now I have an object fooCollection, which is an object containing an undefined number of foos. Each property is a string equals to fooId. How could I define an accurate interface for fooCollection?
So far I came up with this:
interface FooCollection {
[key: string]: Foo;
}
-How could I tell ts that the number of property could be anything?
-Can I be more precise about the prop name, saying that it's fooId instead of any string?
Upvotes: 5
Views: 6627
Reputation: 30879
The index signature [key: string]: Foo
already allows any number of properties (zero or more).
Writing a single type that enforces that the name of each property matches the fooId
of the Foo
object is beyond the capabilities of TypeScript's type system. You could write a FooCollection
type that is generic in the set of IDs used, and that will allow you to write a generic function to validate handwritten FooCollection
literals:
interface Foo<Id extends string> {
fooId: Id;
otherStuff: any;
}
type FooCollection<Ids extends string> = { [Id in Ids]: Foo<Id> };
function checkFooCollection<Ids extends string>
(fooCollection: FooCollection<Ids>) {
return fooCollection;
}
// OK
let c1 = checkFooCollection({
a: {fooId: "a", otherStuff: 5}
});
// Error
let c2 = checkFooCollection({
a: {fooId: "b", otherStuff: 5}
});
But if you are building FooCollection
objects at runtime, this approach is unlikely to give you any more meaningful checking than your original approach.
Upvotes: 9