Mac*_*zyk 6 javascript typescript typescript-generics typescript-typings
我需要实现一个GetClassParameter<T>
像这样工作的类型:
class Foo<T> {
}
type foo = Foo<string>
type x = GetClassParameter<foo>; // should be string
Run Code Online (Sandbox Code Playgroud)
很抱歉,如果它是重复的,我找不到它。我只找到了一个硬编码的解决方案(来源):
type GetFooParameter<T extends Foo<any>> = T extends Foo<infer R> ? R : unknown;
Run Code Online (Sandbox Code Playgroud)
我试图做这样的事情:
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
Run Code Online (Sandbox Code Playgroud)
以上几乎有效,但需要 BaseT 具有value: T
属性。
假设目标类只有一个泛型参数,有没有办法在不硬编码任何东西的情况下做到这一点?
再接再厉,未果。
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
Run Code Online (Sandbox Code Playgroud)
目前是不可能的。尽管如此,我还是尝试了一种 hack 方法来定义具有 value 属性的 BaseT,然后将其删除。它不起作用。如果有人有类似的想法以节省您的时间,我会将其添加为参考。操场
我正在添加一个变通方法,我使用它来获取 2 个没有共同点的类的类参数类型(只需添加额外的条件,它就可以扩展到涵盖更多类)。
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
Run Code Online (Sandbox Code Playgroud)
目前还无法完成 - 纯粹作为一种类型。有一个开放问题,旨在允许传递更高种类的泛型类型: https: //github.com/microsoft/TypeScript/issues/1213
对于许多尝试输入高度可修改的 js-libs(例如 levelup)的人来说,这是一个祸根。
只是为了给你一个更简单的例子来说明不起作用的事情:
interface Dummy<T> {};
declare function getParam<P, T extends Dummy<P>>(a: T): P;
let a = getParam(null as Dummy<string>);
Run Code Online (Sandbox Code Playgroud)
这里是unknown
唯一真正的解决方法是将通用参数作为假属性移动到虚拟接口中 - 但是传递给它的所有内容都需要定义假属性 - 或者你回到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>);
Run Code Online (Sandbox Code Playgroud)
a 是现在string
,但打字稿仍然不知道P
是什么
归档时间: |
|
查看次数: |
412 次 |
最近记录: |