Reputation: 6085
I am trying to do something like that in Typescript :
type A = 'stuff'
type B = {
[x: string]: {
active?: {
[name: string] : A
}
[name: string] : A
}
}
But I get : Property 'active' of type '{ [name: string]: A; } | undefined' is not assignable to string index type 'A'.
What I understand is that active
is also recognized as a member of [name: string]. Is there aanything I can do to precise that active
might contain something different from the other keys?
I hope this is not a duplicate, I had a hard time finding the good way to describe the problem in Google.
** Update: **
The following code fail with Typescript
type ImageName = 'test'
type IconEntry = { [name: string]: ImageName }
type Icons = {
[namespace: string]: IconEntry & {
active?: IconEntry;
};
}
const icons: Icons = {
buttons: {
switch: 'test',
active: {
switch: 'test'
}
}
}
Type '{ switch: "test"; active: { switch: "test"; }; }' is not assignable to type 'IconEntry & { active?: IconEntry | undefined; }'.
Type '{ switch: "test"; active: { switch: "test"; }; }' is not assignable to type 'IconEntry'.
Property 'active' is incompatible with index signature.
Type '{ switch: "test"; }' is not assignable to type '"test"'.(2322)
input.ts(4, 3): The expected type comes from this index signature.
Upvotes: 0
Views: 187
Reputation: 1074276
The only difference I see in active
is that it's A | undefined
instead of just A
. You can define that with an intersection type:
type A = "stuff";
type B = {
[x: string]: {[name: string] : A} & {active?: A}
// −−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
};
With that, assuming you have let b: B
, then b["x"].active
will have the type "stuff" | undefined
and b["x"].foo
will have the type "stuff"
.
The same approach works if you want active
to have a completely different type, unrelated to A
:
type A = "stuff";
type A1 = "other stuff";
type B = {
[x: string]: { [name: string]: A } & { active?: A1 }
};
Upvotes: 3