Florent Arlandis
Florent Arlandis

Reputation: 925

define interface: object with unknown number and name of properties

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

Answers (1)

Matt McCutchen
Matt McCutchen

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

Related Questions