1 year ago
#338194
LaboDJ
Typescript: problem with intersection of types containing a subset of specialized arrays
I've a problem with intersection of types containing array members whose type is a subset of a specific type. It's harder to explain for me than simply show you the code.
This is a custom type
type MyType = 'A' | 'B' | 'C' | 'D';
This is the generic interface for the "base" object
interface Base<A = {}, B = {}> {
stringMember: string;
arrayMember: MyType[];
objectMember: {
something: boolean;
} & A;
b: B;
}
I need to specialize arrayMember, objectMember and b memebers like so
type A_Object_1 = {
somethingElse: number;
};
type B_Object_1 = {
aMember: boolean;
};
// Specialized type 1
type Specialized_1 = Base<A_Object_1, B_Object_1> & {
arrayMember: ['A'];
};
// Specialized type 1 object, this is OK
const a_OK: Specialized_1 = {
stringMember: 'hi',
arrayMember: ['A'],
objectMember: {something: true, somethingElse: 3},
b: {aMember: true},
};
and so
type A_Object_2 = {
anything: boolean;
};
type B_Object_2 = {
bMember: number;
};
type Specialized_2 = Base<A_Object_2, B_Object_2> & {
arrayMember: ['B'];
};
// Specialized type 2 object, this is OK
const b_OK: Specialized_2 = {
stringMember: 'hello',
arrayMember: ['B'],
objectMember: {something: true, anything: true},
b: {bMember: 3},
};
I need an intersection type between Specialized_1 and Specialized_2, it should be like this
{
stringMember: string;
arrayMember: ['A', 'B'];
objectMember: {
something: boolean;
somethingElse: number;
anything: boolean;
};
b: {aMember: boolean; bMember: number};
}
I do that the following (maybe wrong) way
type Specialized_3 = Specialized_1 & Specialized_2;
The members that are objects are ok, since they contain both members from Specialized_1 & Specialized_2 Anyway there is a problem with the array type that is never, I see why, there is no intersection between ['A'] and ['B'],
const c_Problem: Specialized_3 = {
stringMember: 'hi there',
arrayMember: ['A', 'B'], // Error here because arrayMember: never
objectMember: {something: true, somethingElse: 3, anything: false}, // OK
b: {aMember: false, bMember: 8}, // OK
};
It's been 2 days I'm thinking about that and I can't figure it out... Moreover I find difficult to find the search keywords for this very specific problem.
Any help?
EDIT:
Thanks to @AlekseyL.I made some progress, I can use Omit
to omit arrayMember
from the intersected object and than union it later "manually"
I can do this using a generic type like so:
type PossibleSolution<T1 extends Base, T2 extends Base> = Omit<T1 & T2, 'arrayMember'> & {
arrayMember: [T1['arrayMember'][number], T2['arrayMember'][number]];
};
type Specialized_Test = PossibleSolution<Specialized_1, Specialized_2>;
const d_OK: Specialized_Test = {
stringMember: 'hi there',
arrayMember: ['A', 'B'], // OK
objectMember: {something: true, somethingElse: 3, anything: false}, // OK
b: {aMember: false, bMember: 8}, // OK
};
The use of the generic type is for convenience since I need to reuse that here and there in my code.
This solution works, but only to intersect 2 objects, if I need to intersect 3 objects I have to delcare a different generic type
Now the problem is, how can I modify PossibileSolution
generic type to intersect N SpecializedObjects
?
arrays
typescript
types
union
intersection
0 Answers
Your Answer