Reputation: 9979
declare interface timezoneSyntax {
region: string;
en: {
x: string;
offset: {
EST?: number;
EDT?: number;
[key: string]: number;
};
};
it: {
x: string;
}
}
How to make the following object optional and also en
generic?
en: {
x: string;
offset: {
EST?: number;
EDT?: number;
[key: string]: number;
};
};
I have tried to convert en
to [key: string]?
But it is showing error. Please advice.
Upvotes: 3
Views: 18150
Reputation: 153
Indexes of the form [key: string]: T
can be optional. You can try to use Partial
interface timezoneSyntax {
page: Partial<{ [key: string]: number }>;
}
Upvotes: 9
Reputation: 2078
Indexes of the form [key: string]: T
can be considered as being always optional, so no need to specify it with the ?
notation.
However, specifying an index signature like that forces all interface properties to have the same T
type as the key. For example, region
would result in
Property 'region' of type 'string' is not assignable to string index type '{ x: string; offset: { ... }; }'
This is because an index signature [key: string]: T
simply dictates how all interface properties should be like. An alternative would be to use [key: string]: any
but you would loosen up your type safety.
From my understanding, this is not a side effect that you want so you should reconsider the use of index keys in this interface and find a different approach.
Proposal
Instead of using a language-specific property name (en
, it
, es
, etc), use the generic language
as a name. If you also need to know what language you are dealing with, then that should be added to the language
model as name
.
You would end up with something like this:
declare interface timezoneSyntax {
region: string;
language: {
name: string; // `en`, `it`, `es`, etc
x: string;
offset: {
EST?: number;
EDT?: number;
[key: string]: number;
};
};
}
Further Reading
Indexable Types - Official TypeScript Documentation
Index Signatures - TypeScript Deep Dive
Upvotes: 9
Reputation: 285
BTW, It already becomes optional. But, if you still want to explicitly do that then you can do something like this.
declare interface timezoneSyntax {
region: string;
en: {
x: string;
offset:
| {
EST?: number;
EDT?: number;
[key: string]: number;
}
| {
EST?: number;
EDT?: number;
};
};
it: {
x: string;
};
}
Upvotes: 0