Reputation: 717
I Have A Type with two generic parameters
type FirstLevelType<A, Z> = {
_: "typeCheck";
};
But I Need Wrap this type with another
type TestWrapperType<T, U> = FirstLevelType<T, U>;
After I have create variable with TestWrapperType, I need to get generic parameters.
const a: TestWrapperType<{ cat: string }, { dog: number }> = {
_: "typeCheck",
};
But I can use only FirstLevelType to prevent growing code length, because wrapper types can be created many times.
type ExtendFirst = typeof a extends FirstLevelType<infer T, infer U>
? T
: "not extended";
Resulted type = unknown
Excepted type = {cat: string}
type ExtendWrapper = typeof a extends TestWrapperType<infer T, infer U>
? T
: "not extended";
Resulted type = {cat: string}
Excepted type = {cat: string}
Why ExtendFirst type is unknown? And how can I solve this issue.
[Update 1]
If FirstLevelType declared as interface, when Resulted Type will be correct. However, when my wrapper has other properties, resulted type unknow again.
type TestWrapperType<T, U> = FirstLevelType<T, U> & {
seal?: boolean;
};
Upvotes: 2
Views: 462
Reputation: 33111
If you want to make it work, just use interface
for FirstLevelType
instead of type
.
// used interface instead of type
interface FirstLevelType<A, Z> {
_: "typeCheck";
};
type TestWrapperType<T, U> = FirstLevelType<T, U>;
const a: TestWrapperType<{ cat: string }, { dog: number }> = {
_: "typeCheck",
};
type ExtendFirst = typeof a extends FirstLevelType<infer T, infer _>
? T
: "not extended";
type ExtendWrapper = typeof a extends TestWrapperType<infer T, infer _>
? T
: "not extended";
I believe this is because interfaces are lazy evaluated when types
- eagerly.
If FirstLevelType declared as interface, when Resulted Type will be correct. However, when my wrapper has other properties, resulted type unknow again.
Since your TestWrapperType
might be extended, you should infer these rest
props:
type FirstLevelType<A, Z> = {
_: "typeCheck";
};
type TestWrapperType<T, U> = FirstLevelType<T, U> & {
seal?: boolean;
}
const a: TestWrapperType<{ cat: string }, { dog: number }> = {
_: "typeCheck",
};
// { cat: string; }
type ExtendFirst = typeof a extends FirstLevelType<infer T, infer _> & infer RestProps
? T
: "not extended";
Now you can use type
for FirstLevelType
Upvotes: 2