好吧,在我在github开票之前,我想确保我没有做错任何事。我希望问题是自我解释的:
class A {}
class B {
static A = A;
}
function a<T>(a: T) {}
// this is fine
const b = new B.A;
// "B" refers only to a type but is used as a namespace.
a<B.A>(1);
我不能以这种方式引用某种类型吗?
此外,虽然实例化将类型推断为:
b = A
B.A = typeof A
B = B
它推断最后一行:
B = any
因此,VS Code可以跳转到第一个的定义,但是不能找到第二个的引用。
是的,这看起来很奇怪。
更新: 我收到的第一个答案证明是错误的,因为这种语法将导致typeof的类型:
// arguments of type "A" cannot be assigned to parameters of type "typeof A", property "prototype" is missing.
a<(typeof B)['A']>(b);
即使我添加了一个显式的构造函数类型,事情也会变得更糟:
// this will make things worse
class B {
static A: { new (): A } = A;
}
答案 0 :(得分:2)
我不应该以这种方式引用某种类型吗?
不,不是在TypeScript中。
当你有
时class A {}
class B {
static A = A;
}
您可以仅使用B.A
作为值,而不是类型。这可能会令人困惑,因为TypeScript中的类既可以用作值也可以用作类型,但只有类的行为类似,其他任何东西都不同。
因此B.A
是一个值,它的值为class A
,此值的类型为typeof A
(typeof A
是您在使用类时获得的值类型位置,而不是价值位置)。
如果您需要使用B.A
的类型作为泛型类型参数,则可以执行以下操作:
a<(typeof B)['A']>(A);
说明:A
是B类static part
的成员。您使用typeof B
引用类的静态部分,并引用[]
的成员类型indexed access type operator。
上面的这个函数a
接受类A
的构造函数。如果您确实希望函数a
接受A
的实例,则应以不同方式声明B.A
:
class A {}
class B {
static A: A;
}
现在编译
a<(typeof B)['A']>(new A());
<强>更新强>
如果您希望将B.A
初始化为A
的构造函数,但仍然能够访问A
的实例端,则必须等到TypeScript 2.8。它will have a feature that enables obtaining instance type from constructor type - 此代码在npm i typescript@next
之后编译:
class A {}
class B {
static A = A;
}
function a<T>(a: T) { }
const b = new B.A;
type Constructor<T> = { new(...args: any[]): T };
type Instance<C> = C extends Constructor < infer T > ? T : never;
a<Instance<(typeof B)['A']>>(b);