admin管理员组文章数量:1330640
I need to implement a type GetClassParameter<T>
that would work like this:
class Foo<T> {
}
type foo = Foo<string>
type x = GetClassParameter<foo>; // should be string
I'm sorry if it's a duplicate, I couldn't find it. I only found a hardcoded solution (source):
type GetFooParameter<T extends Foo<any>> = T extends Foo<infer R> ? R : unknown;
I tried to do something like this:
class Foo<T> {
public value: T;
public value2: string;
constructor (value: T) {
this.value = value;
}
}
type BaseT<T> = {
value: T // if removed, it wouldn't work
}
type GetClassParameter<T extends BaseT<any>> = T extends BaseT<infer R> ? R : unknown;
type x = GetClassParameter<foo> // string - almost works, requires shared property with a T
The above almost works but requires BaseT to have a value: T
property.
Is there a way to do it without hardcoding anything, assuming the target class has only one generic parameter?
Update:
Another take, unsuccessful.
type ClassLike<T> = (new <T>(...args: any[]) => any);
type GetClassParameter<T extends ClassLike<any>> = T extends ClassLike<infer R> ? R : unknown;
type x = GetClassParameter<foo> // error, does not satisfy constraint
Update 2
It's not possible currently. Nevertheless, I tried a hack to define BaseT with value property and then removed it. It doesn't work. I'm adding it as a reference if someone had a similar idea to save you time. playground
Update 3
I'm adding a workaround I'm using to get the class parameter type for 2 classes that have nothing in mon (it can be extended to cover more classes just by adding additional conditional).
playground
class Alpha<T> {
private a: T;
}
class Beta<T> {
private b: T;
}
type GetClassParameterForAlphaBeta<T extends Alpha<any> | Beta<any>> =
T extends Alpha<infer R>
? R : T extends Beta<infer R>
? R : unknown;
type alpha = Alpha<string>
type beta = Beta<number>
type x = GetClassParameterForAlphaBeta<alpha> // string
type y = GetClassParameterForAlphaBeta<beta> // number
I need to implement a type GetClassParameter<T>
that would work like this:
class Foo<T> {
}
type foo = Foo<string>
type x = GetClassParameter<foo>; // should be string
I'm sorry if it's a duplicate, I couldn't find it. I only found a hardcoded solution (source):
type GetFooParameter<T extends Foo<any>> = T extends Foo<infer R> ? R : unknown;
I tried to do something like this:
class Foo<T> {
public value: T;
public value2: string;
constructor (value: T) {
this.value = value;
}
}
type BaseT<T> = {
value: T // if removed, it wouldn't work
}
type GetClassParameter<T extends BaseT<any>> = T extends BaseT<infer R> ? R : unknown;
type x = GetClassParameter<foo> // string - almost works, requires shared property with a T
The above almost works but requires BaseT to have a value: T
property.
Is there a way to do it without hardcoding anything, assuming the target class has only one generic parameter?
Update:
Another take, unsuccessful.
type ClassLike<T> = (new <T>(...args: any[]) => any);
type GetClassParameter<T extends ClassLike<any>> = T extends ClassLike<infer R> ? R : unknown;
type x = GetClassParameter<foo> // error, does not satisfy constraint
Update 2
It's not possible currently. Nevertheless, I tried a hack to define BaseT with value property and then removed it. It doesn't work. I'm adding it as a reference if someone had a similar idea to save you time. playground
Update 3
I'm adding a workaround I'm using to get the class parameter type for 2 classes that have nothing in mon (it can be extended to cover more classes just by adding additional conditional).
playground
class Alpha<T> {
private a: T;
}
class Beta<T> {
private b: T;
}
type GetClassParameterForAlphaBeta<T extends Alpha<any> | Beta<any>> =
T extends Alpha<infer R>
? R : T extends Beta<infer R>
? R : unknown;
type alpha = Alpha<string>
type beta = Beta<number>
type x = GetClassParameterForAlphaBeta<alpha> // string
type y = GetClassParameterForAlphaBeta<beta> // number
Share
Improve this question
edited Apr 16, 2021 at 7:34
Maciej Kravchyk
asked Apr 15, 2021 at 18:26
Maciej KravchykMaciej Kravchyk
16.7k7 gold badges70 silver badges81 bronze badges
8
-
Your updated try can take
GetClassParameter<typeof Foo>
, if that also works for you – hackape Commented Apr 15, 2021 at 18:50 -
You are right about that. However, passing
GetClassParameter<typeof foo>
doesn't seem to work. – Maciej Kravchyk Commented Apr 15, 2021 at 18:55 -
1
And the feature that takes the general form of
UtilType<F<T>> => T
is not supported by TS. Higher kinded type is the term, and TS doesn’t have it. So forget perfect solution, best you can get is workarounds with limitations. Your two takes are actually good enough. – hackape Commented Apr 15, 2021 at 18:59 - 1 I cannot find the issue anymore, but typescript omits the information of generics if they are unused. It is a design limitation. – Mirco S. Commented Apr 15, 2021 at 19:05
- 1 I don’t have better answer for your problem, you’ve hit the limit of TS. FYI I wrote an answer about higher kinded type in TS years ago. Only remotely related to your problem. If you wanna dig deeper you can take a look. – hackape Commented Apr 15, 2021 at 19:08
1 Answer
Reset to default 4Cannot be done yet - purely as a type. There is an open issue that aims to allow passing higher-kind generic types through: https://github./microsoft/TypeScript/issues/1213
Its an issue that is a bane to many trying to type highly moddable js-libs (like levelup).
Just to give you a much easier example of something that doesn't work:
interface Dummy<T> {};
declare function getParam<P, T extends Dummy<P>>(a: T): P;
let a = getParam(null as Dummy<string>);
here a is unknown
the only real work around is to move the generic parameter into the dummy interface as a fake property - but then everything passed to this will need that fake property defined too - or you're back to unknown
interface Dummy<T> {
a?: T
};
declare function getParam<P, T extends Dummy<P>>(a: T): T["a"]
let a = getParam(null as Foo<string>);
a is now string
but typescript still has no idea what P
is
本文标签: javascriptTypeScriptget type of generic class parameterStack Overflow
版权声明:本文标题:javascript - TypeScript - get type of generic class parameter - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742256881a2441790.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论