Reputation: 6943
I have an interface called CreateForumValues, which is essentially a more specific interface than one called Values.
I have a function (here called test(values)
) that takes in it an object of interface Values:
export interface Values {
[name: string]: string;
}
export interface CreateForumValues {
siteUrl: string;
name: string;
shortName: string;
}
export const createForumDefaults: CreateForumValues = {
siteUrl: "",
name: "",
shortName: "",
};
function Test({ values }: { values: Values }) {
// do something with values
}
Test({ values: createForumDefaults });
I would expect that since CreateForumValues is a more specific, and basically subset of Values, that it would be passable with TypeScript, but I am getting this error:
Type 'CreateForumValues' is not assignable to type 'Values'.
Index signature for type 'string' is missing in type 'CreateForumValues'.ts(2322)
which doesn't make a lot of sense because each of the indexes are essentially strings.
What needs to be done to make these two compatible with each other?
Also, this will be in react, and Test would really be called in JSX like so:
<Test values={createForumDefaults}/>
and there will be different collections of values passed into Test that will be similar to CreateForumValues, but with different property sets.
Upvotes: 0
Views: 51
Reputation: 187004
{ [name: string]: string; }
This says that you can pass any string as an index, and get a string back.
export interface CreateForumValues {
siteUrl: string;
name: string;
shortName: string;
}
This says you can pass 3 specific strings as an index, and get a string back. All other strings are not allowed.
Which means your Test
function expects that you can do value.whatever
and get a string. CreateForumValues
does not conform to that contract.
That's what this error means:
Index signature for type 'string' is missing in type 'CreateForumValues'.
So in order for a type to extend a type with an index signature, it must also have an index signature.
The simplest way to do that is probably to extend the original type when creating an interface.
export interface CreateForumValues extends Values {
siteUrl: string;
name: string;
shortName: string;
}
I would also declare the base type like this, in order to capture the fact that some properties may be missing in sub types.
interface Values {
[name: string]: string | undefined;
}
Upvotes: 1
Reputation: 95614
You'll need to add [name: string]: string
to your CreateForumValues or have CreateForumValues extend Values.
Despite the fact that all values you've defined are strings, other definitions might extend from yours and define incompatible other values like this:
interface CreateExtendedForumValues extends CreateForumValues {
notAString: SomeComplexObjectType;
}
You could also define Values to have string keys and unknown type, but at that point Values might not provide very much value.
Upvotes: 1