Let's say the interface has some known properties with their types, and can have additional ones with unknown keys and some other types, something like:
interface Foo {
length: number;
[key: string]: string;
}
const foo : Foo = {
length: 1,
txt: "TXT",
};
TS error:
Property 'length' of type 'number' is not assignable to string index type 'string'.
How should such an interface be typed?
[key: string]: string;
this prevents the Foo
interface to have none string properties (in your example, number
).
What you can do is to separate the known and unknown properties in two interfaces and define your target type as a union type like below:
interface Foo {
length: number;
}
interface Bar {
[key: string]: string ;
}
type FooBar = Foo | Bar;
const foo : FooBar = {
length: 1, // its ok defined in foo
txt: "TXT", // string is ok
baz : 3 // error because its not string
};
Playground Link
Check out this snippet it explain the point well
interface ArrStr {
[key: string]: string | number; // Must accommodate all members
[index: number]: string; // Can be a subset of string indexer
// Just an example member
length: number;
}
You can check this article for more details (i picked the snippet from there)
https://basarat.gitbook.io/typescript/type-system/index-signatures
For this element
Having both string and number indexers
This is not a common use case, but TypeScript compiler supports it nonetheless. However, it has the restriction that the string indexer is more strict than the number indexer. This is intentional e.g. to allow typing stuff like:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With